Differentially encode all MC register lists.

This simplifies MCRegisterInfo and shrinks the target descriptions a bit
more.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160758 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-07-25 21:41:37 +00:00
parent b8cd66b5d7
commit 303c909d5b
2 changed files with 50 additions and 78 deletions

View File

@ -148,7 +148,6 @@ private:
unsigned NumClasses; // Number of entries in the array
unsigned NumRegUnits; // Number of regunits.
const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
const uint16_t *RegLists; // Pointer to the reglists array
const uint16_t *DiffLists; // Pointer to the difflists array
const char *RegStrings; // Pointer to the string table.
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
@ -168,25 +167,6 @@ private:
DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
public:
/// RegListIterator. This iterator class is used to traverse lists of
/// super-registers, sub-registers, and overlapping registers. Don't use it
/// directly, use one of the sub-classes defined below.
class RegListIterator {
const uint16_t *Pos;
public:
explicit RegListIterator(const uint16_t *Table)
: Pos(Table) {}
/// isValid - Return false when the end of the list is reached.
bool isValid() const { return *Pos; }
/// Dereference the iterator to get the current register.
unsigned operator*() const { return *Pos; }
/// Pre-increment. Move to the next register.
void operator++() { ++Pos; }
};
/// DiffListIterator - Base iterator class that can traverse the
/// differentially encoded register and regunit lists in DiffLists.
/// Don't use this class directly, use one of the specialized sub-classes
@ -233,8 +213,8 @@ public:
}
};
// These iterators are allowed to sub-class RegListIterator and
// DiffListIterator and access internal list pointers.
// These iterators are allowed to sub-class DiffListIterator and access
// internal list pointers.
friend class MCSubRegIterator;
friend class MCSuperRegIterator;
friend class MCRegAliasIterator;
@ -247,7 +227,6 @@ public:
const MCRegisterClass *C, unsigned NC,
const uint16_t (*RURoots)[2],
unsigned NRU,
const uint16_t *RL,
const uint16_t *DL,
const char *Strings,
const uint16_t *SubIndices,
@ -257,7 +236,6 @@ public:
NumRegs = NR;
RAReg = RA;
Classes = C;
RegLists = RL;
DiffLists = DL;
RegStrings = Strings;
NumClasses = NC;
@ -431,26 +409,34 @@ public:
// aliasing registers. Use these iterator classes to traverse the lists.
/// MCSubRegIterator enumerates all sub-registers of Reg.
class MCSubRegIterator : public MCRegisterInfo::RegListIterator {
class MCSubRegIterator : public MCRegisterInfo::DiffListIterator {
public:
MCSubRegIterator(unsigned Reg, const MCRegisterInfo *MCRI)
: RegListIterator(MCRI->RegLists + MCRI->get(Reg).SubRegs) {}
MCSubRegIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs);
++*this;
}
};
/// MCSuperRegIterator enumerates all super-registers of Reg.
class MCSuperRegIterator : public MCRegisterInfo::RegListIterator {
class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
public:
MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI)
: RegListIterator(MCRI->RegLists + MCRI->get(Reg).SuperRegs) {}
MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
++*this;
}
};
/// MCRegAliasIterator enumerates all registers aliasing Reg.
/// If IncludeSelf is set, Reg itself is included in the list.
class MCRegAliasIterator : public MCRegisterInfo::RegListIterator {
class MCRegAliasIterator : public MCRegisterInfo::DiffListIterator {
public:
MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI, bool IncludeSelf)
: RegListIterator(MCRI->RegLists + MCRI->get(Reg).Overlaps + !IncludeSelf)
{}
MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI,
bool IncludeSelf) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).Overlaps);
// Initially, the iterator points to Reg itself.
if (!IncludeSelf)
++*this;
}
};
inline

View File

@ -479,10 +479,6 @@ public:
}
};
static void printRegister(raw_ostream &OS, const CodeGenRegister *Reg) {
OS << getQualifiedName(Reg->TheDef);
}
static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
OS << getEnumName(VT);
}
@ -517,6 +513,19 @@ DiffVec &diffEncode(DiffVec &V, unsigned InitVal, ArrayRef<unsigned> List) {
return V;
}
template<typename Iter>
static
DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {
assert(V.empty() && "Clear DiffVec before diffEncode.");
uint16_t Val = uint16_t(InitVal);
for (Iter I = Begin; I != End; ++I) {
uint16_t Cur = (*I)->EnumValue;
V.push_back(Cur - Val);
Val = Cur;
}
return V;
}
static void printDiff16(raw_ostream &OS, uint16_t Val) {
OS << Val;
}
@ -537,12 +546,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
// The lists of sub-registers, super-registers, and overlaps all go in the
// same array. That allows us to share suffixes.
typedef std::vector<const CodeGenRegister*> RegVec;
SmallVector<RegVec, 4> SubRegLists(Regs.size());
SmallVector<RegVec, 4> OverlapLists(Regs.size());
SequenceToOffsetTable<RegVec, CodeGenRegister::Less> RegSeqs;
// Differentially encoded lists.
SequenceToOffsetTable<DiffVec> DiffSeqs;
SmallVector<DiffVec, 4> SubRegLists(Regs.size());
SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
SmallVector<DiffVec, 4> OverlapLists(Regs.size());
SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
SmallVector<unsigned, 4> RegUnitInitScale(Regs.size());
@ -557,37 +566,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
// Compute the ordered sub-register list.
SetVector<const CodeGenRegister*> SR;
Reg->addSubRegsPreOrder(SR, RegBank);
RegVec &SubRegList = SubRegLists[i];
SubRegList.assign(SR.begin(), SR.end());
RegSeqs.add(SubRegList);
diffEncode(SubRegLists[i], Reg->EnumValue, SR.begin(), SR.end());
DiffSeqs.add(SubRegLists[i]);
// Super-registers are already computed.
const RegVec &SuperRegList = Reg->getSuperRegs();
RegSeqs.add(SuperRegList);
diffEncode(SuperRegLists[i], Reg->EnumValue,
SuperRegList.begin(), SuperRegList.end());
DiffSeqs.add(SuperRegLists[i]);
// The list of overlaps doesn't need to have any particular order, except
// Reg itself must be the first element. Pick an ordering that has one of
// the other lists as a suffix.
RegVec &OverlapList = OverlapLists[i];
const RegVec &Suffix = SubRegList.size() > SuperRegList.size() ?
SubRegList : SuperRegList;
CodeGenRegister::Set Omit(Suffix.begin(), Suffix.end());
// First element is Reg itself.
OverlapList.push_back(Reg);
Omit.insert(Reg);
// Any elements not in Suffix.
// The list of overlaps doesn't need to have any particular order, and Reg
// itself must be omitted.
DiffVec &OverlapList = OverlapLists[i];
CodeGenRegister::Set OSet;
Reg->computeOverlaps(OSet, RegBank);
std::set_difference(OSet.begin(), OSet.end(),
Omit.begin(), Omit.end(),
std::back_inserter(OverlapList),
CodeGenRegister::Less());
// Finally, Suffix itself.
OverlapList.insert(OverlapList.end(), Suffix.begin(), Suffix.end());
RegSeqs.add(OverlapList);
OSet.erase(Reg);
diffEncode(OverlapList, Reg->EnumValue, OSet.begin(), OSet.end());
DiffSeqs.add(OverlapList);
// Differentially encode the register unit list, seeded by register number.
// First compute a scale factor that allows more diff-lists to be reused:
@ -616,18 +611,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
}
// Compute the final layout of the sequence table.
RegSeqs.layout();
DiffSeqs.layout();
OS << "namespace llvm {\n\n";
const std::string &TargetName = Target.getName();
// Emit the shared table of register lists.
OS << "extern const uint16_t " << TargetName << "RegLists[] = {\n";
RegSeqs.emit(OS, printRegister);
OS << "};\n\n";
// Emit the shared table of differential lists.
OS << "extern const uint16_t " << TargetName << "RegDiffLists[] = {\n";
DiffSeqs.emit(OS, printDiff16);
@ -647,9 +636,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
const CodeGenRegister *Reg = Regs[i];
OS << " { " << RegStrings.get(Reg->getName()) << ", "
<< RegSeqs.get(OverlapLists[i]) << ", "
<< RegSeqs.get(SubRegLists[i]) << ", "
<< RegSeqs.get(Reg->getSuperRegs()) << ", "
<< DiffSeqs.get(OverlapLists[i]) << ", "
<< DiffSeqs.get(SubRegLists[i]) << ", "
<< DiffSeqs.get(SuperRegLists[i]) << ", "
<< (DiffSeqs.get(RegUnitLists[i])*16 + RegUnitInitScale[i]) << " },\n";
}
OS << "};\n\n"; // End of register descriptors...
@ -789,7 +778,6 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
<< RegisterClasses.size() << ", "
<< TargetName << "RegUnitRoots, "
<< RegBank.getNumNativeRegUnits() << ", "
<< TargetName << "RegLists, "
<< TargetName << "RegDiffLists, "
<< TargetName << "RegStrings, ";
if (SubRegIndices.size() != 0)
@ -1148,7 +1136,6 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
OS << "extern const uint16_t " << TargetName << "RegLists[];\n";
OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n";
OS << "extern const char " << TargetName << "RegStrings[];\n";
OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n";
@ -1169,7 +1156,6 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
<< " " << TargetName << "RegUnitRoots,\n"
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
<< " " << TargetName << "RegLists,\n"
<< " " << TargetName << "RegDiffLists,\n"
<< " " << TargetName << "RegStrings,\n"
<< " ";