mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-15 07:34:33 +00:00
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:
parent
b8cd66b5d7
commit
303c909d5b
@ -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
|
||||
|
@ -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"
|
||||
<< " ";
|
||||
|
Loading…
x
Reference in New Issue
Block a user