mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Simplify ownership of RegClasses by using list<CodeGenRegisterClass> instead of vector<CodeGenRegisterClass*>
This complicates a few algorithms due to not having random access, but not by a huge degree I don't think (open to debate/design discussion/etc). llvm-svn: 223261
This commit is contained in:
parent
afd7d9143a
commit
2afe696d92
@ -1089,9 +1089,9 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
|
|||||||
RegisterSetSet RegisterSets;
|
RegisterSetSet RegisterSets;
|
||||||
|
|
||||||
// Gather the defined sets.
|
// Gather the defined sets.
|
||||||
for (const CodeGenRegisterClass *RC : RegClassList)
|
for (const CodeGenRegisterClass &RC : RegClassList)
|
||||||
RegisterSets.insert(RegisterSet(RC->getOrder().begin(),
|
RegisterSets.insert(
|
||||||
RC->getOrder().end()));
|
RegisterSet(RC.getOrder().begin(), RC.getOrder().end()));
|
||||||
|
|
||||||
// Add any required singleton sets.
|
// Add any required singleton sets.
|
||||||
for (Record *Rec : SingletonRegisters) {
|
for (Record *Rec : SingletonRegisters) {
|
||||||
@ -1160,19 +1160,19 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Name the register classes which correspond to a user defined RegisterClass.
|
// Name the register classes which correspond to a user defined RegisterClass.
|
||||||
for (const CodeGenRegisterClass *RC : RegClassList) {
|
for (const CodeGenRegisterClass &RC : RegClassList) {
|
||||||
// Def will be NULL for non-user defined register classes.
|
// Def will be NULL for non-user defined register classes.
|
||||||
Record *Def = RC->getDef();
|
Record *Def = RC.getDef();
|
||||||
if (!Def)
|
if (!Def)
|
||||||
continue;
|
continue;
|
||||||
ClassInfo *CI = RegisterSetClasses[RegisterSet(RC->getOrder().begin(),
|
ClassInfo *CI = RegisterSetClasses[RegisterSet(RC.getOrder().begin(),
|
||||||
RC->getOrder().end())];
|
RC.getOrder().end())];
|
||||||
if (CI->ValueName.empty()) {
|
if (CI->ValueName.empty()) {
|
||||||
CI->ClassName = RC->getName();
|
CI->ClassName = RC.getName();
|
||||||
CI->Name = "MCK_" + RC->getName();
|
CI->Name = "MCK_" + RC.getName();
|
||||||
CI->ValueName = RC->getName();
|
CI->ValueName = RC.getName();
|
||||||
} else
|
} else
|
||||||
CI->ValueName = CI->ValueName + "," + RC->getName();
|
CI->ValueName = CI->ValueName + "," + RC.getName();
|
||||||
|
|
||||||
RegisterClassClasses.insert(std::make_pair(Def, CI));
|
RegisterClassClasses.insert(std::make_pair(Def, CI));
|
||||||
}
|
}
|
||||||
|
@ -810,34 +810,34 @@ static bool testSubClass(const CodeGenRegisterClass *A,
|
|||||||
/// Register classes with the same registers, spill size, and alignment form a
|
/// Register classes with the same registers, spill size, and alignment form a
|
||||||
/// clique. They will be ordered alphabetically.
|
/// clique. They will be ordered alphabetically.
|
||||||
///
|
///
|
||||||
static int TopoOrderRC(CodeGenRegisterClass *const *PA,
|
static bool TopoOrderRC(const CodeGenRegisterClass &PA,
|
||||||
CodeGenRegisterClass *const *PB) {
|
const CodeGenRegisterClass &PB) {
|
||||||
auto *A = *PA;
|
auto *A = &PA;
|
||||||
auto *B = *PB;
|
auto *B = &PB;
|
||||||
if (A == B)
|
if (A == B)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Order by ascending spill size.
|
// Order by ascending spill size.
|
||||||
if (A->SpillSize < B->SpillSize)
|
if (A->SpillSize < B->SpillSize)
|
||||||
return -1;
|
return true;
|
||||||
if (A->SpillSize > B->SpillSize)
|
if (A->SpillSize > B->SpillSize)
|
||||||
return 1;
|
return false;
|
||||||
|
|
||||||
// Order by ascending spill alignment.
|
// Order by ascending spill alignment.
|
||||||
if (A->SpillAlignment < B->SpillAlignment)
|
if (A->SpillAlignment < B->SpillAlignment)
|
||||||
return -1;
|
return true;
|
||||||
if (A->SpillAlignment > B->SpillAlignment)
|
if (A->SpillAlignment > B->SpillAlignment)
|
||||||
return 1;
|
return false;
|
||||||
|
|
||||||
// Order by descending set size. Note that the classes' allocation order may
|
// Order by descending set size. Note that the classes' allocation order may
|
||||||
// not have been computed yet. The Members set is always vaild.
|
// not have been computed yet. The Members set is always vaild.
|
||||||
if (A->getMembers().size() > B->getMembers().size())
|
if (A->getMembers().size() > B->getMembers().size())
|
||||||
return -1;
|
return true;
|
||||||
if (A->getMembers().size() < B->getMembers().size())
|
if (A->getMembers().size() < B->getMembers().size())
|
||||||
return 1;
|
return false;
|
||||||
|
|
||||||
// Finally order by name as a tie breaker.
|
// Finally order by name as a tie breaker.
|
||||||
return StringRef(A->getName()).compare(B->getName());
|
return StringRef(A->getName()) < B->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CodeGenRegisterClass::getQualifiedName() const {
|
std::string CodeGenRegisterClass::getQualifiedName() const {
|
||||||
@ -854,13 +854,13 @@ void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
|
|||||||
|
|
||||||
// Visit backwards so sub-classes are seen first.
|
// Visit backwards so sub-classes are seen first.
|
||||||
for (auto I = RegClasses.rbegin(), E = RegClasses.rend(); I != E; ++I) {
|
for (auto I = RegClasses.rbegin(), E = RegClasses.rend(); I != E; ++I) {
|
||||||
CodeGenRegisterClass &RC = **I;
|
CodeGenRegisterClass &RC = *I;
|
||||||
RC.SubClasses.resize(RegClasses.size());
|
RC.SubClasses.resize(RegClasses.size());
|
||||||
RC.SubClasses.set(RC.EnumValue);
|
RC.SubClasses.set(RC.EnumValue);
|
||||||
|
|
||||||
// Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
|
// Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
|
||||||
for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) {
|
for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) {
|
||||||
CodeGenRegisterClass &SubRC = **I2;
|
CodeGenRegisterClass &SubRC = *I2;
|
||||||
if (RC.SubClasses.test(SubRC.EnumValue))
|
if (RC.SubClasses.test(SubRC.EnumValue))
|
||||||
continue;
|
continue;
|
||||||
if (!testSubClass(&RC, &SubRC))
|
if (!testSubClass(&RC, &SubRC))
|
||||||
@ -871,30 +871,30 @@ void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sweep up missed clique members. They will be immediately preceding RC.
|
// Sweep up missed clique members. They will be immediately preceding RC.
|
||||||
for (auto I2 = std::next(I); I2 != E && testSubClass(&RC, *I2); ++I2)
|
for (auto I2 = std::next(I); I2 != E && testSubClass(&RC, &*I2); ++I2)
|
||||||
RC.SubClasses.set((*I2)->EnumValue);
|
RC.SubClasses.set(I2->EnumValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the SuperClasses lists from the SubClasses vectors.
|
// Compute the SuperClasses lists from the SubClasses vectors.
|
||||||
for (auto *RC : RegClasses) {
|
for (auto &RC : RegClasses) {
|
||||||
const BitVector &SC = RC->getSubClasses();
|
const BitVector &SC = RC.getSubClasses();
|
||||||
auto I = RegClasses.begin();
|
auto I = RegClasses.begin();
|
||||||
for (int s = 0, next_s = SC.find_first(); next_s != -1;
|
for (int s = 0, next_s = SC.find_first(); next_s != -1;
|
||||||
next_s = SC.find_next(s)) {
|
next_s = SC.find_next(s)) {
|
||||||
std::advance(I, next_s - s);
|
std::advance(I, next_s - s);
|
||||||
s = next_s;
|
s = next_s;
|
||||||
if (*I == RC)
|
if (&*I == &RC)
|
||||||
continue;
|
continue;
|
||||||
(*I)->SuperClasses.push_back(RC);
|
I->SuperClasses.push_back(&RC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// With the class hierarchy in place, let synthesized register classes inherit
|
// With the class hierarchy in place, let synthesized register classes inherit
|
||||||
// properties from their closest super-class. The iteration order here can
|
// properties from their closest super-class. The iteration order here can
|
||||||
// propagate properties down multiple levels.
|
// propagate properties down multiple levels.
|
||||||
for (auto *RC : RegClasses)
|
for (auto &RC : RegClasses)
|
||||||
if (!RC->getDef())
|
if (!RC.getDef())
|
||||||
RC->inheritProperties(RegBank);
|
RC.inheritProperties(RegBank);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
|
void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
|
||||||
@ -995,18 +995,18 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) {
|
|||||||
|
|
||||||
// Allocate user-defined register classes.
|
// Allocate user-defined register classes.
|
||||||
for (auto *RC : RCs) {
|
for (auto *RC : RCs) {
|
||||||
RegClasses.push_back(new CodeGenRegisterClass(*this, RC));
|
RegClasses.push_back(CodeGenRegisterClass(*this, RC));
|
||||||
addToMaps(RegClasses.back());
|
addToMaps(&RegClasses.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infer missing classes to create a full algebra.
|
// Infer missing classes to create a full algebra.
|
||||||
computeInferredRegisterClasses();
|
computeInferredRegisterClasses();
|
||||||
|
|
||||||
// Order register classes topologically and assign enum values.
|
// Order register classes topologically and assign enum values.
|
||||||
array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC);
|
RegClasses.sort(TopoOrderRC);
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (auto *RC : RegClasses)
|
for (auto &RC : RegClasses)
|
||||||
RC->EnumValue = i++;
|
RC.EnumValue = i++;
|
||||||
CodeGenRegisterClass::computeSubClasses(*this);
|
CodeGenRegisterClass::computeSubClasses(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,9 +1057,9 @@ CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
|
|||||||
return FoundI->second;
|
return FoundI->second;
|
||||||
|
|
||||||
// Sub-class doesn't exist, create a new one.
|
// Sub-class doesn't exist, create a new one.
|
||||||
RegClasses.push_back(new CodeGenRegisterClass(*this, Name, K));
|
RegClasses.push_back(CodeGenRegisterClass(*this, Name, K));
|
||||||
addToMaps(RegClasses.back());
|
addToMaps(&RegClasses.back());
|
||||||
return RegClasses.back();
|
return &RegClasses.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) {
|
CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) {
|
||||||
@ -1247,11 +1247,11 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
|
|||||||
// For simplicitly make the SetID the same as EnumValue.
|
// For simplicitly make the SetID the same as EnumValue.
|
||||||
IntEqClasses UberSetIDs(Registers.size()+1);
|
IntEqClasses UberSetIDs(Registers.size()+1);
|
||||||
std::set<unsigned> AllocatableRegs;
|
std::set<unsigned> AllocatableRegs;
|
||||||
for (auto *RegClass : RegBank.getRegClasses()) {
|
for (auto &RegClass : RegBank.getRegClasses()) {
|
||||||
if (!RegClass->Allocatable)
|
if (!RegClass.Allocatable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const CodeGenRegister::Set &Regs = RegClass->getMembers();
|
const CodeGenRegister::Set &Regs = RegClass.getMembers();
|
||||||
if (Regs.empty())
|
if (Regs.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1525,16 +1525,16 @@ void CodeGenRegBank::computeRegUnitSets() {
|
|||||||
|
|
||||||
// Compute a unique RegUnitSet for each RegClass.
|
// Compute a unique RegUnitSet for each RegClass.
|
||||||
auto &RegClasses = getRegClasses();
|
auto &RegClasses = getRegClasses();
|
||||||
for (auto *RC : RegClasses) {
|
for (auto &RC : RegClasses) {
|
||||||
if (!RC->Allocatable)
|
if (!RC.Allocatable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Speculatively grow the RegUnitSets to hold the new set.
|
// Speculatively grow the RegUnitSets to hold the new set.
|
||||||
RegUnitSets.resize(RegUnitSets.size() + 1);
|
RegUnitSets.resize(RegUnitSets.size() + 1);
|
||||||
RegUnitSets.back().Name = RC->getName();
|
RegUnitSets.back().Name = RC.getName();
|
||||||
|
|
||||||
// Compute a sorted list of units in this class.
|
// Compute a sorted list of units in this class.
|
||||||
RC->buildRegUnitSet(RegUnitSets.back().Units);
|
RC.buildRegUnitSet(RegUnitSets.back().Units);
|
||||||
|
|
||||||
// Find an existing RegUnitSet.
|
// Find an existing RegUnitSet.
|
||||||
std::vector<RegUnitSet>::const_iterator SetI =
|
std::vector<RegUnitSet>::const_iterator SetI =
|
||||||
@ -1634,20 +1634,20 @@ void CodeGenRegBank::computeRegUnitSets() {
|
|||||||
// For each register class, list the UnitSets that are supersets.
|
// For each register class, list the UnitSets that are supersets.
|
||||||
RegClassUnitSets.resize(RegClasses.size());
|
RegClassUnitSets.resize(RegClasses.size());
|
||||||
int RCIdx = -1;
|
int RCIdx = -1;
|
||||||
for (auto *RC : RegClasses) {
|
for (auto &RC : RegClasses) {
|
||||||
++RCIdx;
|
++RCIdx;
|
||||||
if (!RC->Allocatable)
|
if (!RC.Allocatable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Recompute the sorted list of units in this class.
|
// Recompute the sorted list of units in this class.
|
||||||
std::vector<unsigned> RCRegUnits;
|
std::vector<unsigned> RCRegUnits;
|
||||||
RC->buildRegUnitSet(RCRegUnits);
|
RC.buildRegUnitSet(RCRegUnits);
|
||||||
|
|
||||||
// Don't increase pressure for unallocatable regclasses.
|
// Don't increase pressure for unallocatable regclasses.
|
||||||
if (RCRegUnits.empty())
|
if (RCRegUnits.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DEBUG(dbgs() << "RC " << RC->getName() << " Units: \n";
|
DEBUG(dbgs() << "RC " << RC.getName() << " Units: \n";
|
||||||
for (unsigned i = 0, e = RCRegUnits.size(); i < e; ++i) dbgs()
|
for (unsigned i = 0, e = RCRegUnits.size(); i < e; ++i) dbgs()
|
||||||
<< RegUnits[RCRegUnits[i]].getRoots()[0]->getName() << " ";
|
<< RegUnits[RCRegUnits[i]].getRoots()[0]->getName() << " ";
|
||||||
dbgs() << "\n UnitSetIDs:");
|
dbgs() << "\n UnitSetIDs:");
|
||||||
@ -1732,12 +1732,13 @@ void CodeGenRegBank::computeDerivedInfo() {
|
|||||||
// returns a maximal register class for all X.
|
// returns a maximal register class for all X.
|
||||||
//
|
//
|
||||||
void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
||||||
// This loop might add more subclasses, invalidating iterators, so don't use
|
assert(!RegClasses.empty());
|
||||||
// range-for or iterator-based loops (unless RegClasses is changed to use a
|
// Stash the iterator to the last element so that this loop doesn't visit
|
||||||
// container with appropriate iterator invalidation semantics for this).
|
// elements added by the getOrCreateSubClass call within it.
|
||||||
for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) {
|
for (auto I = RegClasses.begin(), E = std::prev(RegClasses.end());
|
||||||
|
I != std::next(E); ++I) {
|
||||||
CodeGenRegisterClass *RC1 = RC;
|
CodeGenRegisterClass *RC1 = RC;
|
||||||
CodeGenRegisterClass *RC2 = RegClasses[rci];
|
CodeGenRegisterClass *RC2 = &*I;
|
||||||
if (RC1 == RC2)
|
if (RC1 == RC2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1844,9 +1845,11 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
|
|||||||
// this loop. They will never be useful.
|
// this loop. They will never be useful.
|
||||||
// Careful if trying to transform this loop to use iterators - as this loop
|
// Careful if trying to transform this loop to use iterators - as this loop
|
||||||
// will add new classes it will invalidate iterators to RegClasses.
|
// will add new classes it will invalidate iterators to RegClasses.
|
||||||
for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
|
assert(!RegClasses.empty());
|
||||||
++rci) {
|
for (auto I = std::next(RegClasses.begin(), FirstSubRegRC),
|
||||||
CodeGenRegisterClass &SubRC = *RegClasses[rci];
|
E = std::prev(RegClasses.end());
|
||||||
|
I != std::next(E); ++I) {
|
||||||
|
CodeGenRegisterClass &SubRC = *I;
|
||||||
// Topological shortcut: SubRC members have the wrong shape.
|
// Topological shortcut: SubRC members have the wrong shape.
|
||||||
if (!TopoSigs.anyCommon(SubRC.getTopoSigs()))
|
if (!TopoSigs.anyCommon(SubRC.getTopoSigs()))
|
||||||
continue;
|
continue;
|
||||||
@ -1883,10 +1886,9 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
|||||||
|
|
||||||
// Visit all register classes, including the ones being added by the loop.
|
// Visit all register classes, including the ones being added by the loop.
|
||||||
// Watch out for iterator invalidation here.
|
// Watch out for iterator invalidation here.
|
||||||
// inferMatchingSuperRegClass inside this loop can add new elements to
|
unsigned rci = 0;
|
||||||
// RegClasses, so this loop can't use range-for or even explicit iterators.
|
for (auto &RCR : RegClasses) {
|
||||||
for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
|
CodeGenRegisterClass *RC = &RCR;
|
||||||
CodeGenRegisterClass *RC = RegClasses[rci];
|
|
||||||
|
|
||||||
// Synthesize answers for getSubClassWithSubReg().
|
// Synthesize answers for getSubClassWithSubReg().
|
||||||
inferSubClassWithSubReg(RC);
|
inferSubClassWithSubReg(RC);
|
||||||
@ -1905,10 +1907,11 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
|||||||
// [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci].
|
// [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci].
|
||||||
if (rci + 1 == FirstNewRC) {
|
if (rci + 1 == FirstNewRC) {
|
||||||
unsigned NextNewRC = RegClasses.size();
|
unsigned NextNewRC = RegClasses.size();
|
||||||
for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2)
|
auto I2 = RegClasses.begin();
|
||||||
|
for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2, ++I2)
|
||||||
// This can add more things to RegClasses, be careful about iterator
|
// This can add more things to RegClasses, be careful about iterator
|
||||||
// invalidation of outer loop variables.
|
// invalidation of outer loop variables.
|
||||||
inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC);
|
inferMatchingSuperRegClass(&*I2, FirstNewRC);
|
||||||
FirstNewRC = NextNewRC;
|
FirstNewRC = NextNewRC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1923,8 +1926,7 @@ const CodeGenRegisterClass*
|
|||||||
CodeGenRegBank::getRegClassForRegister(Record *R) {
|
CodeGenRegBank::getRegClassForRegister(Record *R) {
|
||||||
const CodeGenRegister *Reg = getReg(R);
|
const CodeGenRegister *Reg = getReg(R);
|
||||||
const CodeGenRegisterClass *FoundRC = nullptr;
|
const CodeGenRegisterClass *FoundRC = nullptr;
|
||||||
for (const auto *RCP : getRegClasses()) {
|
for (const auto &RC : getRegClasses()) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
if (!RC.contains(Reg))
|
if (!RC.contains(Reg))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ namespace llvm {
|
|||||||
SmallVector<RegUnit, 8> RegUnits;
|
SmallVector<RegUnit, 8> RegUnits;
|
||||||
|
|
||||||
// Register classes.
|
// Register classes.
|
||||||
std::vector<CodeGenRegisterClass*> RegClasses;
|
std::list<CodeGenRegisterClass> RegClasses;
|
||||||
DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
|
DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
|
||||||
typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap;
|
typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap;
|
||||||
RCKeyMap Key2RC;
|
RCKeyMap Key2RC;
|
||||||
@ -609,9 +609,9 @@ namespace llvm {
|
|||||||
RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
|
RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
|
||||||
const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
|
const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
|
||||||
|
|
||||||
std::vector<CodeGenRegisterClass *> &getRegClasses() { return RegClasses; }
|
std::list<CodeGenRegisterClass> &getRegClasses() { return RegClasses; }
|
||||||
|
|
||||||
const std::vector<CodeGenRegisterClass *> &getRegClasses() const {
|
const std::list<CodeGenRegisterClass> &getRegClasses() const {
|
||||||
return RegClasses;
|
return RegClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +233,8 @@ getRegisterVTs(Record *R) const {
|
|||||||
const CodeGenRegister *Reg = getRegBank().getReg(R);
|
const CodeGenRegister *Reg = getRegBank().getReg(R);
|
||||||
std::vector<MVT::SimpleValueType> Result;
|
std::vector<MVT::SimpleValueType> Result;
|
||||||
for (const auto &RC : getRegBank().getRegClasses()) {
|
for (const auto &RC : getRegBank().getRegClasses()) {
|
||||||
if (RC->contains(Reg)) {
|
if (RC.contains(Reg)) {
|
||||||
ArrayRef<MVT::SimpleValueType> InVTs = RC->getValueTypes();
|
ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
|
||||||
Result.insert(Result.end(), InVTs.begin(), InVTs.end());
|
Result.insert(Result.end(), InVTs.begin(), InVTs.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,9 +247,8 @@ getRegisterVTs(Record *R) const {
|
|||||||
|
|
||||||
|
|
||||||
void CodeGenTarget::ReadLegalValueTypes() const {
|
void CodeGenTarget::ReadLegalValueTypes() const {
|
||||||
for (const auto *RC : getRegBank().getRegClasses())
|
for (const auto &RC : getRegBank().getRegClasses())
|
||||||
for (unsigned ri = 0, re = RC->VTs.size(); ri != re; ++ri)
|
LegalValueTypes.insert(LegalValueTypes.end(), RC.VTs.begin(), RC.VTs.end());
|
||||||
LegalValueTypes.push_back(RC->VTs[ri]);
|
|
||||||
|
|
||||||
// Remove duplicates.
|
// Remove duplicates.
|
||||||
std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
|
std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
|
||||||
|
@ -28,18 +28,18 @@ static MVT::SimpleValueType getRegisterValueType(Record *R,
|
|||||||
MVT::SimpleValueType VT = MVT::Other;
|
MVT::SimpleValueType VT = MVT::Other;
|
||||||
const CodeGenRegister *Reg = T.getRegBank().getReg(R);
|
const CodeGenRegister *Reg = T.getRegBank().getReg(R);
|
||||||
|
|
||||||
for (const auto *RC : T.getRegBank().getRegClasses()) {
|
for (const auto &RC : T.getRegBank().getRegClasses()) {
|
||||||
if (!RC->contains(Reg))
|
if (!RC.contains(Reg))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!FoundRC) {
|
if (!FoundRC) {
|
||||||
FoundRC = true;
|
FoundRC = true;
|
||||||
VT = RC->getValueTypeNum(0);
|
VT = RC.getValueTypeNum(0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this occurs in multiple register classes, they all have to agree.
|
// If this occurs in multiple register classes, they all have to agree.
|
||||||
assert(VT == RC->getValueTypeNum(0));
|
assert(VT == RC.getValueTypeNum(0));
|
||||||
}
|
}
|
||||||
return VT;
|
return VT;
|
||||||
}
|
}
|
||||||
|
@ -111,9 +111,9 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
|||||||
if (!Namespace.empty())
|
if (!Namespace.empty())
|
||||||
OS << "namespace " << Namespace << " {\n";
|
OS << "namespace " << Namespace << " {\n";
|
||||||
OS << "enum {\n";
|
OS << "enum {\n";
|
||||||
for (const auto *RC : RegisterClasses)
|
for (const auto &RC : RegisterClasses)
|
||||||
OS << " " << RC->getName() << "RegClassID"
|
OS << " " << RC.getName() << "RegClassID"
|
||||||
<< " = " << RC->EnumValue << ",\n";
|
<< " = " << RC.EnumValue << ",\n";
|
||||||
OS << "\n };\n";
|
OS << "\n };\n";
|
||||||
if (!Namespace.empty())
|
if (!Namespace.empty())
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
@ -177,8 +177,7 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
|
|||||||
<< "const RegClassWeight &" << ClassName << "::\n"
|
<< "const RegClassWeight &" << ClassName << "::\n"
|
||||||
<< "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
|
<< "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
|
||||||
<< " static const RegClassWeight RCWeightTable[] = {\n";
|
<< " static const RegClassWeight RCWeightTable[] = {\n";
|
||||||
for (const auto *RCP : RegBank.getRegClasses()) {
|
for (const auto &RC : RegBank.getRegClasses()) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
const CodeGenRegister::Set &Regs = RC.getMembers();
|
const CodeGenRegister::Set &Regs = RC.getMembers();
|
||||||
if (Regs.empty())
|
if (Regs.empty())
|
||||||
OS << " {0, 0";
|
OS << " {0, 0";
|
||||||
@ -844,8 +843,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
SequenceToOffsetTable<std::string> RegClassStrings;
|
SequenceToOffsetTable<std::string> RegClassStrings;
|
||||||
|
|
||||||
// Emit the register enum value arrays for each RegisterClass
|
// Emit the register enum value arrays for each RegisterClass
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
ArrayRef<Record*> Order = RC.getOrder();
|
ArrayRef<Record*> Order = RC.getOrder();
|
||||||
|
|
||||||
// Give the register class a legal C name if it's anonymous.
|
// Give the register class a legal C name if it's anonymous.
|
||||||
@ -885,9 +883,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
OS << "extern const MCRegisterClass " << TargetName
|
OS << "extern const MCRegisterClass " << TargetName
|
||||||
<< "MCRegisterClasses[] = {\n";
|
<< "MCRegisterClasses[] = {\n";
|
||||||
|
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
|
|
||||||
// Asserts to make sure values will fit in table assuming types from
|
// Asserts to make sure values will fit in table assuming types from
|
||||||
// MCRegisterInfo.h
|
// MCRegisterInfo.h
|
||||||
assert((RC.SpillSize/8) <= 0xffff && "SpillSize too large.");
|
assert((RC.SpillSize/8) <= 0xffff && "SpillSize too large.");
|
||||||
@ -989,11 +985,10 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
const auto &RegisterClasses = RegBank.getRegClasses();
|
const auto &RegisterClasses = RegBank.getRegClasses();
|
||||||
|
|
||||||
if (!RegisterClasses.empty()) {
|
if (!RegisterClasses.empty()) {
|
||||||
OS << "namespace " << RegisterClasses.front()->Namespace
|
OS << "namespace " << RegisterClasses.front().Namespace
|
||||||
<< " { // Register classes\n";
|
<< " { // Register classes\n";
|
||||||
|
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
const std::string &Name = RC.getName();
|
const std::string &Name = RC.getName();
|
||||||
|
|
||||||
// Output the extern for the instance.
|
// Output the extern for the instance.
|
||||||
@ -1030,8 +1025,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
std::set<Record*> AllocatableRegs;
|
std::set<Record*> AllocatableRegs;
|
||||||
|
|
||||||
// Collect allocatable registers.
|
// Collect allocatable registers.
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
ArrayRef<Record*> Order = RC.getOrder();
|
ArrayRef<Record*> Order = RC.getOrder();
|
||||||
|
|
||||||
if (RC.Allocatable)
|
if (RC.Allocatable)
|
||||||
@ -1040,8 +1034,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
|
|
||||||
// Build a shared array of value types.
|
// Build a shared array of value types.
|
||||||
SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
|
SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
|
||||||
for (const auto *RC : RegisterClasses)
|
for (const auto &RC : RegisterClasses)
|
||||||
VTSeqs.add(RC->VTs);
|
VTSeqs.add(RC.VTs);
|
||||||
VTSeqs.layout();
|
VTSeqs.layout();
|
||||||
OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
|
OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
|
||||||
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
|
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
|
||||||
@ -1094,8 +1088,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
SequenceToOffsetTable<IdxList, CodeGenSubRegIndex::Less> SuperRegIdxSeqs;
|
SequenceToOffsetTable<IdxList, CodeGenSubRegIndex::Less> SuperRegIdxSeqs;
|
||||||
BitVector MaskBV(RegisterClasses.size());
|
BitVector MaskBV(RegisterClasses.size());
|
||||||
|
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
OS << "static const uint32_t " << RC.getName() << "SubClassMask[] = {\n ";
|
OS << "static const uint32_t " << RC.getName() << "SubClassMask[] = {\n ";
|
||||||
printBitVectorAsHex(OS, RC.getSubClasses(), 32);
|
printBitVectorAsHex(OS, RC.getSubClasses(), 32);
|
||||||
|
|
||||||
@ -1122,8 +1115,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
|
||||||
// Emit NULL terminated super-class lists.
|
// Emit NULL terminated super-class lists.
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();
|
ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();
|
||||||
|
|
||||||
// Skip classes without supers. We can reuse NullRegClasses.
|
// Skip classes without supers. We can reuse NullRegClasses.
|
||||||
@ -1138,8 +1130,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit methods.
|
// Emit methods.
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
if (!RC.AltOrderSelect.empty()) {
|
if (!RC.AltOrderSelect.empty()) {
|
||||||
OS << "\nstatic inline unsigned " << RC.getName()
|
OS << "\nstatic inline unsigned " << RC.getName()
|
||||||
<< "AltOrderSelect(const MachineFunction &MF) {"
|
<< "AltOrderSelect(const MachineFunction &MF) {"
|
||||||
@ -1171,11 +1162,10 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now emit the actual value-initialized register class instances.
|
// Now emit the actual value-initialized register class instances.
|
||||||
OS << "\nnamespace " << RegisterClasses.front()->Namespace
|
OS << "\nnamespace " << RegisterClasses.front().Namespace
|
||||||
<< " { // Register class instances\n";
|
<< " { // Register class instances\n";
|
||||||
|
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
OS << " extern const TargetRegisterClass " << RC.getName()
|
OS << " extern const TargetRegisterClass " << RC.getName()
|
||||||
<< "RegClass = {\n " << '&' << Target.getName()
|
<< "RegClass = {\n " << '&' << Target.getName()
|
||||||
<< "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "
|
<< "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "
|
||||||
@ -1198,8 +1188,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
|
|
||||||
OS << "\nnamespace {\n";
|
OS << "\nnamespace {\n";
|
||||||
OS << " const TargetRegisterClass* const RegisterClasses[] = {\n";
|
OS << " const TargetRegisterClass* const RegisterClasses[] = {\n";
|
||||||
for (const auto *RC : RegisterClasses)
|
for (const auto &RC : RegisterClasses)
|
||||||
OS << " &" << RC->getQualifiedName() << "RegClass,\n";
|
OS << " &" << RC.getQualifiedName() << "RegClass,\n";
|
||||||
OS << " };\n";
|
OS << " };\n";
|
||||||
OS << "}\n"; // End of anonymous namespace...
|
OS << "}\n"; // End of anonymous namespace...
|
||||||
|
|
||||||
@ -1240,8 +1230,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
else
|
else
|
||||||
PrintFatalError("Too many register classes.");
|
PrintFatalError("Too many register classes.");
|
||||||
OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";
|
OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";
|
||||||
for (const auto *RCP : RegisterClasses) {
|
for (const auto &RC : RegisterClasses) {
|
||||||
const CodeGenRegisterClass &RC = *RCP;
|
|
||||||
OS << " {\t// " << RC.getName() << "\n";
|
OS << " {\t// " << RC.getName() << "\n";
|
||||||
for (auto &Idx : SubRegIndices) {
|
for (auto &Idx : SubRegIndices) {
|
||||||
if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
|
if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
|
||||||
|
Loading…
Reference in New Issue
Block a user