Use deque<T> rather than vector<T*> since it provides the same invalidation semantics (at least when removal is not needed) without the extra indirection/ownership complexity

Order matters for this container, it seems (using a forward_list and
replacing the original push_backs with emplace_fronts caused test
failures). I didn't look too deeply into why.

(& in retrospect, I might go back & change some of the forward_lists I
introduced to deques anyway - since most don't require removal, deque is
a more memory-friendly data structure (moderate locality while not
invalidating pointers))

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222950 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie
2014-11-29 07:04:51 +00:00
parent 71f69c81db
commit c7d3454376
3 changed files with 38 additions and 47 deletions

View File

@@ -931,7 +931,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) {
getSubRegIdx(SRIs[i]); getSubRegIdx(SRIs[i]);
// Build composite maps from ComposedOf fields. // Build composite maps from ComposedOf fields.
for (auto &Idx : SubRegIndices) for (auto &Idx : SubRegIndices)
Idx->updateComponents(*this); Idx.updateComponents(*this);
// Read in the register definitions. // Read in the register definitions.
std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
@@ -1017,24 +1017,16 @@ CodeGenRegBank::~CodeGenRegBank() {
// Create a synthetic CodeGenSubRegIndex without a corresponding Record. // Create a synthetic CodeGenSubRegIndex without a corresponding Record.
CodeGenSubRegIndex* CodeGenSubRegIndex*
CodeGenRegBank::createSubRegIndex(StringRef Name, StringRef Namespace) { CodeGenRegBank::createSubRegIndex(StringRef Name, StringRef Namespace) {
//auto SubRegIndicesSize = std::distance(SubRegIndices.begin(), SubRegIndices.end()); SubRegIndices.emplace_back(Name, Namespace, SubRegIndices.size() + 1);
//SubRegIndices.emplace_front(Name, Namespace, SubRegIndicesSize + 1); return &SubRegIndices.back();
//return &SubRegIndices.front();
CodeGenSubRegIndex *Idx = new CodeGenSubRegIndex(Name, Namespace,
SubRegIndices.size() + 1);
SubRegIndices.push_back(Idx);
return Idx;
} }
CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) { CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) {
CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def]; CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def];
if (Idx) if (Idx)
return Idx; return Idx;
Idx = new CodeGenSubRegIndex(Def, SubRegIndices.size() + 1); SubRegIndices.emplace_back(Def, SubRegIndices.size() + 1);
SubRegIndices.push_back(Idx); Idx = &SubRegIndices.back();
//auto SubRegIndicesSize = std::distance(SubRegIndices.begin(), SubRegIndices.end());
//SubRegIndices.emplace_front(Def, SubRegIndicesSize + 1);
//Idx = &SubRegIndices.front();
return Idx; return Idx;
} }
@@ -1187,8 +1179,8 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
// Determine mask of lanes that cover their registers. // Determine mask of lanes that cover their registers.
CoveringLanes = ~0u; CoveringLanes = ~0u;
for (auto &Idx : SubRegIndices) { for (auto &Idx : SubRegIndices) {
if (Idx->getComposites().empty()) { if (Idx.getComposites().empty()) {
Idx->LaneMask = 1u << Bit; Idx.LaneMask = 1u << Bit;
// Share bit 31 in the unlikely case there are more than 32 leafs. // Share bit 31 in the unlikely case there are more than 32 leafs.
// //
// Sharing bits is harmless; it allows graceful degradation in targets // Sharing bits is harmless; it allows graceful degradation in targets
@@ -1203,7 +1195,7 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
// is no longer covering its registers. // is no longer covering its registers.
CoveringLanes &= ~(1u << Bit); CoveringLanes &= ~(1u << Bit);
} else { } else {
Idx->LaneMask = 0; Idx.LaneMask = 0;
} }
} }
@@ -1212,10 +1204,10 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
// Inherit lanes from composites. // Inherit lanes from composites.
for (const auto &Idx : SubRegIndices) { for (const auto &Idx : SubRegIndices) {
unsigned Mask = Idx->computeLaneMask(); unsigned Mask = Idx.computeLaneMask();
// If some super-registers without CoveredBySubRegs use this index, we can // If some super-registers without CoveredBySubRegs use this index, we can
// no longer assume that the lanes are covering their registers. // no longer assume that the lanes are covering their registers.
if (!Idx->AllSuperRegsCovered) if (!Idx.AllSuperRegsCovered)
CoveringLanes &= ~Mask; CoveringLanes &= ~Mask;
} }
} }
@@ -1804,20 +1796,20 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
// Find matching classes for all SRSets entries. Iterate in SubRegIndex // Find matching classes for all SRSets entries. Iterate in SubRegIndex
// numerical order to visit synthetic indices last. // numerical order to visit synthetic indices last.
for (const auto &SubIdx : SubRegIndices) { for (const auto &SubIdx : SubRegIndices) {
SubReg2SetMap::const_iterator I = SRSets.find(SubIdx); SubReg2SetMap::const_iterator I = SRSets.find(&SubIdx);
// Unsupported SubRegIndex. Skip it. // Unsupported SubRegIndex. Skip it.
if (I == SRSets.end()) if (I == SRSets.end())
continue; continue;
// In most cases, all RC registers support the SubRegIndex. // In most cases, all RC registers support the SubRegIndex.
if (I->second.size() == RC->getMembers().size()) { if (I->second.size() == RC->getMembers().size()) {
RC->setSubClassWithSubReg(SubIdx, RC); RC->setSubClassWithSubReg(&SubIdx, RC);
continue; continue;
} }
// This is a real subset. See if we have a matching class. // This is a real subset. See if we have a matching class.
CodeGenRegisterClass *SubRC = CodeGenRegisterClass *SubRC =
getOrCreateSubClass(RC, &I->second, getOrCreateSubClass(RC, &I->second,
RC->getName() + "_with_" + I->first->getName()); RC->getName() + "_with_" + I->first->getName());
RC->setSubClassWithSubReg(SubIdx, SubRC); RC->setSubClassWithSubReg(&SubIdx, SubRC);
} }
} }
@@ -1839,7 +1831,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
// Skip indexes that aren't fully supported by RC's registers. This was // Skip indexes that aren't fully supported by RC's registers. This was
// computed by inferSubClassWithSubReg() above which should have been // computed by inferSubClassWithSubReg() above which should have been
// called first. // called first.
if (RC->getSubClassWithSubReg(SubIdx) != RC) if (RC->getSubClassWithSubReg(&SubIdx) != RC)
continue; continue;
// Build list of (Super, Sub) pairs for this SubIdx. // Build list of (Super, Sub) pairs for this SubIdx.
@@ -1848,7 +1840,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(), for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
RE = RC->getMembers().end(); RI != RE; ++RI) { RE = RC->getMembers().end(); RI != RE; ++RI) {
const CodeGenRegister *Super = *RI; const CodeGenRegister *Super = *RI;
const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second; const CodeGenRegister *Sub = Super->getSubRegs().find(&SubIdx)->second;
assert(Sub && "Missing sub-register"); assert(Sub && "Missing sub-register");
SSPairs.push_back(std::make_pair(Super, Sub)); SSPairs.push_back(std::make_pair(Super, Sub));
TopoSigs.set(Sub->getTopoSig()); TopoSigs.set(Sub->getTopoSig());
@@ -1871,14 +1863,14 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
continue; continue;
// RC injects completely into SubRC. // RC injects completely into SubRC.
if (SubSet.size() == SSPairs.size()) { if (SubSet.size() == SSPairs.size()) {
SubRC->addSuperRegClass(SubIdx, RC); SubRC->addSuperRegClass(&SubIdx, RC);
continue; continue;
} }
// Only a subset of RC maps into SubRC. Make sure it is represented by a // Only a subset of RC maps into SubRC. Make sure it is represented by a
// class. // class.
getOrCreateSubClass(RC, &SubSet, RC->getName() + getOrCreateSubClass(RC, &SubSet, RC->getName() + "_with_" +
"_with_" + SubIdx->getName() + SubIdx.getName() + "_in_" +
"_in_" + SubRC->getName()); SubRC->getName());
} }
} }
} }

View File

@@ -28,7 +28,7 @@
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
#include <forward_list> #include <deque>
namespace llvm { namespace llvm {
class CodeGenRegBank; class CodeGenRegBank;
@@ -449,8 +449,7 @@ namespace llvm {
class CodeGenRegBank { class CodeGenRegBank {
SetTheory Sets; SetTheory Sets;
//std::forward_list<CodeGenSubRegIndex> SubRegIndices; std::deque<CodeGenSubRegIndex> SubRegIndices;
std::vector<CodeGenSubRegIndex*> SubRegIndices;
DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx; DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx;
CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace); CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace);
@@ -531,7 +530,9 @@ namespace llvm {
// Sub-register indices. The first NumNamedIndices are defined by the user // Sub-register indices. The first NumNamedIndices are defined by the user
// in the .td files. The rest are synthesized such that all sub-registers // in the .td files. The rest are synthesized such that all sub-registers
// have a unique name. // have a unique name.
std::vector<CodeGenSubRegIndex*> &getSubRegIndices() { return SubRegIndices; } const std::deque<CodeGenSubRegIndex> &getSubRegIndices() const {
return SubRegIndices;
}
// Find a SubRegIndex form its Record def. // Find a SubRegIndex form its Record def.
CodeGenSubRegIndex *getSubRegIdx(Record*); CodeGenSubRegIndex *getSubRegIdx(Record*);

View File

@@ -140,13 +140,13 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
auto &SubRegIndices = Bank.getSubRegIndices(); auto &SubRegIndices = Bank.getSubRegIndices();
if (!SubRegIndices.empty()) { if (!SubRegIndices.empty()) {
OS << "\n// Subregister indices\n"; OS << "\n// Subregister indices\n";
std::string Namespace = SubRegIndices.front()->getNamespace(); std::string Namespace = SubRegIndices.front().getNamespace();
if (!Namespace.empty()) if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n"; OS << "namespace " << Namespace << " {\n";
OS << "enum {\n NoSubRegister,\n"; OS << "enum {\n NoSubRegister,\n";
unsigned i = 0; unsigned i = 0;
for (const auto &Idx : SubRegIndices) for (const auto &Idx : SubRegIndices)
OS << " " << Idx->getName() << ",\t// " << ++i << "\n"; OS << " " << Idx.getName() << ",\t// " << ++i << "\n";
OS << " NUM_TARGET_SUBREGS\n};\n"; OS << " NUM_TARGET_SUBREGS\n};\n";
if (!Namespace.empty()) if (!Namespace.empty())
OS << "}\n"; OS << "}\n";
@@ -648,7 +648,7 @@ RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
for (const auto &Idx : SubRegIndices) { for (const auto &Idx : SubRegIndices) {
unsigned Found = ~0u; unsigned Found = ~0u;
for (unsigned r = 0, re = Rows.size(); r != re; ++r) { for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
if (combine(Idx, Rows[r])) { if (combine(&Idx, Rows[r])) {
Found = r; Found = r;
break; break;
} }
@@ -657,7 +657,7 @@ RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
Found = Rows.size(); Found = Rows.size();
Rows.resize(Found + 1); Rows.resize(Found + 1);
Rows.back().resize(SubRegIndicesSize); Rows.back().resize(SubRegIndicesSize);
combine(Idx, Rows.back()); combine(&Idx, Rows.back());
} }
RowMap.push_back(Found); RowMap.push_back(Found);
} }
@@ -800,9 +800,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
<< TargetName << "SubRegIdxRanges[] = {\n"; << TargetName << "SubRegIdxRanges[] = {\n";
OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n"; OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n";
for (const auto &Idx : SubRegIndices) { for (const auto &Idx : SubRegIndices) {
OS << " { " << Idx->Offset << ", " OS << " { " << Idx.Offset << ", " << Idx.Size << " },\t// "
<< Idx->Size << Idx.getName() << "\n";
<< " },\t// " << Idx->getName() << "\n";
} }
OS << "};\n\n"; OS << "};\n\n";
@@ -1056,7 +1055,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << "\nstatic const char *const SubRegIndexNameTable[] = { \""; OS << "\nstatic const char *const SubRegIndexNameTable[] = { \"";
for (const auto &Idx : SubRegIndices) { for (const auto &Idx : SubRegIndices) {
OS << Idx->getName(); OS << Idx.getName();
OS << "\", \""; OS << "\", \"";
} }
OS << "\" };\n\n"; OS << "\" };\n\n";
@@ -1064,8 +1063,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
// Emit SubRegIndex lane masks, including 0. // Emit SubRegIndex lane masks, including 0.
OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n"; OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n";
for (const auto &Idx : SubRegIndices) { for (const auto &Idx : SubRegIndices) {
OS << format(" 0x%08x, // ", Idx->LaneMask) OS << format(" 0x%08x, // ", Idx.LaneMask) << Idx.getName() << '\n';
<< Idx->getName() << '\n';
} }
OS << " };\n\n"; OS << " };\n\n";
@@ -1110,13 +1108,13 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
IdxList &SRIList = SuperRegIdxLists[rc]; IdxList &SRIList = SuperRegIdxLists[rc];
for (auto &Idx : SubRegIndices) { for (auto &Idx : SubRegIndices) {
MaskBV.reset(); MaskBV.reset();
RC.getSuperRegClasses(Idx, MaskBV); RC.getSuperRegClasses(&Idx, MaskBV);
if (MaskBV.none()) if (MaskBV.none())
continue; continue;
SRIList.push_back(Idx); SRIList.push_back(&Idx);
OS << "\n "; OS << "\n ";
printBitVectorAsHex(OS, MaskBV, 32); printBitVectorAsHex(OS, MaskBV, 32);
OS << "// " << Idx->getName(); OS << "// " << Idx.getName();
} }
SuperRegIdxSeqs.add(SRIList); SuperRegIdxSeqs.add(SRIList);
OS << "\n};\n\n"; OS << "\n};\n\n";
@@ -1253,11 +1251,11 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
const CodeGenRegisterClass &RC = *RegisterClasses[rci]; const CodeGenRegisterClass &RC = *RegisterClasses[rci];
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))
OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx->getName() OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
<< " -> " << SRC->getName() << "\n"; << " -> " << SRC->getName() << "\n";
else else
OS << " 0,\t// " << Idx->getName() << "\n"; OS << " 0,\t// " << Idx.getName() << "\n";
} }
OS << " },\n"; OS << " },\n";
} }