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:
Matthias Braun 2014-12-10 01:12:56 +00:00
parent 08c7b086a9
commit 84cc6ec889
4 changed files with 125 additions and 6 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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&);

View File

@ -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"