mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 23:20:54 +00:00
Tablegen'erate lanemasks for register units.
Now we can relate lanemasks in a virtual register to register units. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223889 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
08c7b086a9
commit
84cc6ec889
@ -114,6 +114,10 @@ struct MCRegisterDesc {
|
||||
// RegUnits - Points to the list of register units. The low 4 bits holds the
|
||||
// Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
|
||||
uint32_t RegUnits;
|
||||
|
||||
/// Index into list with lane mask sequences. The sequence contains a lanemask
|
||||
/// for every register unit.
|
||||
uint16_t RegUnitLaneMasks;
|
||||
};
|
||||
|
||||
/// MCRegisterInfo base class - We assume that the target defines a static
|
||||
@ -157,6 +161,8 @@ private:
|
||||
unsigned NumRegUnits; // Number of regunits.
|
||||
const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table.
|
||||
const MCPhysReg *DiffLists; // Pointer to the difflists array
|
||||
const unsigned *RegUnitMaskSequences; // Pointer to lane mask sequences
|
||||
// for register units.
|
||||
const char *RegStrings; // Pointer to the string table.
|
||||
const char *RegClassStrings; // Pointer to the class strings.
|
||||
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
|
||||
@ -229,6 +235,7 @@ public:
|
||||
friend class MCSubRegIterator;
|
||||
friend class MCSuperRegIterator;
|
||||
friend class MCRegUnitIterator;
|
||||
friend class MCRegUnitMaskIterator;
|
||||
friend class MCRegUnitRootIterator;
|
||||
|
||||
/// \brief Initialize MCRegisterInfo, called by TableGen
|
||||
@ -239,6 +246,7 @@ public:
|
||||
const MCPhysReg (*RURoots)[2],
|
||||
unsigned NRU,
|
||||
const MCPhysReg *DL,
|
||||
const unsigned *RUMS,
|
||||
const char *Strings,
|
||||
const char *ClassStrings,
|
||||
const uint16_t *SubIndices,
|
||||
@ -251,6 +259,7 @@ public:
|
||||
PCReg = PC;
|
||||
Classes = C;
|
||||
DiffLists = DL;
|
||||
RegUnitMaskSequences = RUMS;
|
||||
RegStrings = Strings;
|
||||
RegClassStrings = ClassStrings;
|
||||
NumClasses = NC;
|
||||
@ -513,6 +522,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// MCRegUnitIterator enumerates a list of register units and their associated
|
||||
/// lane masks for Reg. The register units are in ascending numerical order.
|
||||
class MCRegUnitMaskIterator {
|
||||
MCRegUnitIterator RUIter;
|
||||
const unsigned *MaskListIter;
|
||||
public:
|
||||
MCRegUnitMaskIterator() {}
|
||||
/// Constructs an iterator that traverses the register units and their
|
||||
/// associated LaneMasks in Reg.
|
||||
MCRegUnitMaskIterator(unsigned Reg, const MCRegisterInfo *MCRI)
|
||||
: RUIter(Reg, MCRI) {
|
||||
uint16_t Idx = MCRI->get(Reg).RegUnitLaneMasks;
|
||||
MaskListIter = &MCRI->RegUnitMaskSequences[Idx];
|
||||
}
|
||||
|
||||
/// Returns a (RegUnit, LaneMask) pair.
|
||||
std::pair<unsigned,unsigned> operator*() const {
|
||||
return std::make_pair(*RUIter, *MaskListIter);
|
||||
}
|
||||
|
||||
/// Returns true if this iterator is not yet at the end.
|
||||
bool isValid() const { return RUIter.isValid(); }
|
||||
|
||||
/// Moves to the next position.
|
||||
void operator++() {
|
||||
++MaskListIter;
|
||||
++RUIter;
|
||||
}
|
||||
};
|
||||
|
||||
// Each register unit has one or two root registers. The complete set of
|
||||
// registers containing a register unit is the union of the roots and their
|
||||
// super-registers. All registers aliasing Unit can be visited like this:
|
||||
|
@ -1763,6 +1763,41 @@ void CodeGenRegBank::computeRegUnitSets() {
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenRegBank::computeRegUnitLaneMasks() {
|
||||
for (auto &Register : Registers) {
|
||||
// Create an initial lane mask for all register units.
|
||||
const auto &RegUnits = Register.getRegUnits();
|
||||
CodeGenRegister::RegUnitLaneMaskList RegUnitLaneMasks(RegUnits.size(), 0);
|
||||
// Iterate through SubRegisters.
|
||||
typedef CodeGenRegister::SubRegMap SubRegMap;
|
||||
const SubRegMap &SubRegs = Register.getSubRegs();
|
||||
for (SubRegMap::const_iterator S = SubRegs.begin(),
|
||||
SE = SubRegs.end(); S != SE; ++S) {
|
||||
CodeGenRegister *SubReg = S->second;
|
||||
// Ignore non-leaf subregisters, their lane masks are fully covered by
|
||||
// the leaf subregisters anyway.
|
||||
if (SubReg->getSubRegs().size() != 0)
|
||||
continue;
|
||||
CodeGenSubRegIndex *SubRegIndex = S->first;
|
||||
const CodeGenRegister *SubRegister = S->second;
|
||||
unsigned LaneMask = SubRegIndex->LaneMask;
|
||||
// Distribute LaneMask to Register Units touched.
|
||||
for (const auto &SUI : SubRegister->getRegUnits()) {
|
||||
bool Found = false;
|
||||
for (size_t u = 0, ue = RegUnits.size(); u < ue; ++u) {
|
||||
if (SUI == RegUnits[u]) {
|
||||
RegUnitLaneMasks[u] |= LaneMask;
|
||||
assert(!Found);
|
||||
Found = true;
|
||||
}
|
||||
}
|
||||
assert(Found);
|
||||
}
|
||||
}
|
||||
Register.setRegUnitLaneMasks(RegUnitLaneMasks);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenRegBank::computeDerivedInfo() {
|
||||
computeComposites();
|
||||
computeSubRegLaneMasks();
|
||||
@ -1775,6 +1810,8 @@ void CodeGenRegBank::computeDerivedInfo() {
|
||||
// supersets for the union of overlapping sets.
|
||||
computeRegUnitSets();
|
||||
|
||||
computeRegUnitLaneMasks();
|
||||
|
||||
// Get the weight of each set.
|
||||
for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx)
|
||||
RegUnitSets[Idx].Weight = getRegUnitSetWeight(RegUnitSets[Idx].Units);
|
||||
|
@ -198,6 +198,7 @@ namespace llvm {
|
||||
|
||||
// List of register units in ascending order.
|
||||
typedef SmallVector<unsigned, 16> RegUnitList;
|
||||
typedef SmallVector<unsigned, 16> RegUnitLaneMaskList;
|
||||
|
||||
// How many entries in RegUnitList are native?
|
||||
unsigned NumNativeRegUnits;
|
||||
@ -206,11 +207,19 @@ namespace llvm {
|
||||
// This is only valid after computeSubRegs() completes.
|
||||
const RegUnitList &getRegUnits() const { return RegUnits; }
|
||||
|
||||
ArrayRef<unsigned> getRegUnitLaneMasks() const {
|
||||
return makeArrayRef(RegUnitLaneMasks).slice(0, NumNativeRegUnits);
|
||||
}
|
||||
|
||||
// Get the native register units. This is a prefix of getRegUnits().
|
||||
ArrayRef<unsigned> getNativeRegUnits() const {
|
||||
return makeArrayRef(RegUnits).slice(0, NumNativeRegUnits);
|
||||
}
|
||||
|
||||
void setRegUnitLaneMasks(const RegUnitLaneMaskList &LaneMasks) {
|
||||
RegUnitLaneMasks = LaneMasks;
|
||||
}
|
||||
|
||||
// Inherit register units from subregisters.
|
||||
// Return true if the RegUnits changed.
|
||||
bool inheritRegUnits(CodeGenRegBank &RegBank);
|
||||
@ -253,6 +262,7 @@ namespace llvm {
|
||||
SuperRegList SuperRegs;
|
||||
DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*> SubReg2Idx;
|
||||
RegUnitList RegUnits;
|
||||
RegUnitLaneMaskList RegUnitLaneMasks;
|
||||
};
|
||||
|
||||
|
||||
@ -544,6 +554,10 @@ namespace llvm {
|
||||
// Compute a lane mask for each sub-register index.
|
||||
void computeSubRegLaneMasks();
|
||||
|
||||
/// Computes a lane mask for each register unit enumerated by a physical
|
||||
/// register.
|
||||
void computeRegUnitLaneMasks();
|
||||
|
||||
public:
|
||||
CodeGenRegBank(RecordKeeper&);
|
||||
|
||||
|
@ -568,6 +568,7 @@ static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
|
||||
// 0 differential which means we can't encode repeated elements.
|
||||
|
||||
typedef SmallVector<uint16_t, 4> DiffVec;
|
||||
typedef SmallVector<unsigned, 4> MaskVec;
|
||||
|
||||
// Differentially encode a sequence of numbers into V. The starting value and
|
||||
// terminating 0 are not added to V, so it will have the same size as List.
|
||||
@ -600,6 +601,10 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) {
|
||||
OS << Val;
|
||||
}
|
||||
|
||||
static void printMask(raw_ostream &OS, unsigned Val) {
|
||||
OS << format("0x%08X", Val);
|
||||
}
|
||||
|
||||
// Try to combine Idx's compose map into Vec if it is compatible.
|
||||
// Return false if it's not possible.
|
||||
static bool combine(const CodeGenSubRegIndex *Idx,
|
||||
@ -803,6 +808,10 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
|
||||
SmallVector<unsigned, 4> RegUnitInitScale(Regs.size());
|
||||
|
||||
// List of lane masks accompanying register unit sequences.
|
||||
SequenceToOffsetTable<MaskVec> LaneMaskSeqs;
|
||||
SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());
|
||||
|
||||
// Keep track of sub-register names as well. These are not differentially
|
||||
// encoded.
|
||||
typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
|
||||
@ -813,7 +822,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
// Precompute register lists for the SequenceToOffsetTable.
|
||||
unsigned i = 0;
|
||||
for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) {
|
||||
for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
|
||||
const auto &Reg = *I;
|
||||
RegStrings.add(Reg.getName());
|
||||
|
||||
@ -860,11 +869,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
Scale = 0;
|
||||
RegUnitInitScale[i] = Scale;
|
||||
DiffSeqs.add(diffEncode(RegUnitLists[i], Scale * Reg.EnumValue, RUs));
|
||||
++i;
|
||||
|
||||
const auto &RUMasks = Reg.getRegUnitLaneMasks();
|
||||
MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
|
||||
assert(LaneMaskVec.empty());
|
||||
LaneMaskVec.insert(LaneMaskVec.begin(), RUMasks.begin(), RUMasks.end());
|
||||
// Terminator mask should not be used inside of the list.
|
||||
#ifndef NDEBUG
|
||||
for (unsigned M : LaneMaskVec) {
|
||||
assert(M != ~0u && "terminator mask should not be part of the list");
|
||||
}
|
||||
#endif
|
||||
LaneMaskSeqs.add(LaneMaskVec);
|
||||
}
|
||||
|
||||
// Compute the final layout of the sequence table.
|
||||
DiffSeqs.layout();
|
||||
LaneMaskSeqs.layout();
|
||||
SubRegIdxSeqs.layout();
|
||||
|
||||
OS << "namespace llvm {\n\n";
|
||||
@ -876,6 +897,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
DiffSeqs.emit(OS, printDiff16);
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the shared table of regunit lane mask sequences.
|
||||
OS << "extern const unsigned " << TargetName << "LaneMaskLists[] = {\n";
|
||||
LaneMaskSeqs.emit(OS, printMask, "~0u");
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the table of sub-register indexes.
|
||||
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
|
||||
SubRegIdxSeqs.emit(OS, printSubRegIndex);
|
||||
@ -899,7 +925,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
OS << "extern const MCRegisterDesc " << TargetName
|
||||
<< "RegDesc[] = { // Descriptors\n";
|
||||
OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0 },\n";
|
||||
OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n";
|
||||
|
||||
// Emit the register descriptors now.
|
||||
i = 0;
|
||||
@ -907,7 +933,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << " { " << RegStrings.get(Reg.getName()) << ", "
|
||||
<< DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
|
||||
<< ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
|
||||
<< (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << " },\n";
|
||||
<< (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << ", "
|
||||
<< LaneMaskSeqs.get(RegUnitLaneMasks[i]) << " },\n";
|
||||
++i;
|
||||
}
|
||||
OS << "};\n\n"; // End of register descriptors...
|
||||
@ -1021,8 +1048,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< Regs.size() + 1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
|
||||
<< RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, "
|
||||
<< RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, "
|
||||
<< TargetName << "RegStrings, " << TargetName << "RegClassStrings, "
|
||||
<< TargetName << "SubRegIdxLists, "
|
||||
<< TargetName << "LaneMaskLists, " << TargetName << "RegStrings, "
|
||||
<< TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, "
|
||||
<< (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n"
|
||||
<< TargetName << "SubRegIdxRanges, " << TargetName
|
||||
<< "RegEncodingTable);\n\n";
|
||||
@ -1349,6 +1376,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// Emit the constructor of the class...
|
||||
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
|
||||
OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
|
||||
OS << "extern const unsigned " << TargetName << "LaneMaskLists[];\n";
|
||||
OS << "extern const char " << TargetName << "RegStrings[];\n";
|
||||
OS << "extern const char " << TargetName << "RegClassStrings[];\n";
|
||||
OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
|
||||
@ -1372,6 +1400,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< " " << TargetName << "RegUnitRoots,\n"
|
||||
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
|
||||
<< " " << TargetName << "RegDiffLists,\n"
|
||||
<< " " << TargetName << "LaneMaskLists,\n"
|
||||
<< " " << TargetName << "RegStrings,\n"
|
||||
<< " " << TargetName << "RegClassStrings,\n"
|
||||
<< " " << TargetName << "SubRegIdxLists,\n"
|
||||
|
Loading…
Reference in New Issue
Block a user