Add TargetRegisterInfo::getCoveringLanes().

This lane mask provides information about which register lanes
completely cover super-registers. See the block comment before
getCoveringLanes().

llvm-svn: 182034
This commit is contained in:
Jakob Stoklund Olesen 2013-05-16 18:03:08 +00:00
parent 7b22c7a38a
commit 4d48e01000
5 changed files with 67 additions and 9 deletions

View File

@ -226,13 +226,15 @@ private:
const unsigned *SubRegIndexLaneMasks;
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
unsigned CoveringLanes;
protected:
TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
regclass_iterator RegClassBegin,
regclass_iterator RegClassEnd,
const char *const *SRINames,
const unsigned *SRILaneMasks);
const unsigned *SRILaneMasks,
unsigned CoveringLanes);
virtual ~TargetRegisterInfo();
public:
@ -362,6 +364,31 @@ public:
return SubRegIndexLaneMasks[SubIdx];
}
/// The lane masks returned by getSubRegIndexLaneMask() above can only be
/// used to determine if sub-registers overlap - they can't be used to
/// determine if a set of sub-registers completely cover another
/// sub-register.
///
/// The X86 general purpose registers have two lanes corresponding to the
/// sub_8bit and sub_8bit_hi sub-registers. Both sub_32bit and sub_16bit have
/// lane masks '3', but the sub_16bit sub-register doesn't fully cover the
/// sub_32bit sub-register.
///
/// On the other hand, the ARM NEON lanes fully cover their registers: The
/// dsub_0 sub-register is completely covered by the ssub_0 and ssub_1 lanes.
/// This is related to the CoveredBySubRegs property on register definitions.
///
/// This function returns a bit mask of lanes that completely cover their
/// sub-registers. More precisely, given:
///
/// Covering = getCoveringLanes();
/// MaskA = getSubRegIndexLaneMask(SubA);
/// MaskB = getSubRegIndexLaneMask(SubB);
///
/// If (MaskA & ~(MaskB & Covering)) == 0, then SubA is completely covered by
/// SubB.
unsigned getCoveringLanes() const { return CoveringLanes; }
/// regsOverlap - Returns true if the two registers are equal or alias each
/// other. The registers may be virtual register.
bool regsOverlap(unsigned regA, unsigned regB) const {

View File

@ -23,10 +23,12 @@ using namespace llvm;
TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
regclass_iterator RCB, regclass_iterator RCE,
const char *const *SRINames,
const unsigned *SRILaneMasks)
const unsigned *SRILaneMasks,
unsigned SRICoveringLanes)
: InfoDesc(ID), SubRegIndexNames(SRINames),
SubRegIndexLaneMasks(SRILaneMasks),
RegClassBegin(RCB), RegClassEnd(RCE) {
RegClassBegin(RCB), RegClassEnd(RCE),
CoveringLanes(SRICoveringLanes) {
}
TargetRegisterInfo::~TargetRegisterInfo() {}

View File

@ -28,7 +28,7 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
: TheDef(R), EnumValue(Enum), LaneMask(0) {
: TheDef(R), EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) {
Name = R->getName();
if (R->getValue("Namespace"))
Namespace = R->getValueAsString("Namespace");
@ -36,7 +36,8 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
unsigned Enum)
: TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), LaneMask(0) {
: TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum),
LaneMask(0), AllSuperRegsCovered(true) {
}
std::string CodeGenSubRegIndex::getQualifiedName() const {
@ -312,6 +313,11 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
PrintFatalError(Loc, "Register " + getName() +
" has itself as a sub-register");
}
// Compute AllSuperRegsCovered.
if (!CoveredBySubRegs)
SI->first->AllSuperRegsCovered = false;
// Ensure that every sub-register has a unique name.
DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*>::iterator Ins =
SubReg2Idx.insert(std::make_pair(SI->second, SI->first)).first;
@ -1195,6 +1201,8 @@ void CodeGenRegBank::computeComposites() {
void CodeGenRegBank::computeSubRegIndexLaneMasks() {
// First assign individual bits to all the leaf indices.
unsigned Bit = 0;
// Determine mask of lanes that cover their registers.
CoveringLanes = ~0u;
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
CodeGenSubRegIndex *Idx = SubRegIndices[i];
if (Idx->getComposites().empty()) {
@ -1206,7 +1214,12 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
// view of lanes beyond the 32nd.
//
// See also the comment for getSubRegIndexLaneMask().
if (Bit < 31) ++Bit;
if (Bit < 31)
++Bit;
else
// Once bit 31 is shared among multiple leafs, the 'lane' it represents
// is no longer covering its registers.
CoveringLanes &= ~(1u << Bit);
} else {
Idx->LaneMask = 0;
}
@ -1216,8 +1229,13 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
// by the sub-register graph? This doesn't occur in any known targets.
// Inherit lanes from composites.
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
SubRegIndices[i]->computeLaneMask();
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
unsigned Mask = SubRegIndices[i]->computeLaneMask();
// If some super-registers without CoveredBySubRegs use this index, we can
// no longer assume that the lanes are covering their registers.
if (!SubRegIndices[i]->AllSuperRegsCovered)
CoveringLanes &= ~Mask;
}
}
namespace {

View File

@ -42,6 +42,10 @@ namespace llvm {
const unsigned EnumValue;
unsigned LaneMask;
// Are all super-registers containing this SubRegIndex covered by their
// sub-registers?
bool AllSuperRegsCovered;
CodeGenSubRegIndex(Record *R, unsigned Enum);
CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
@ -649,6 +653,11 @@ namespace llvm {
// This is used to compute the mask of call-preserved registers from a list
// of callee-saves.
BitVector computeCoveredRegisters(ArrayRef<Record*> Regs);
// Bit mask of lanes that cover their registers. A sub-register index whose
// LaneMask is contained in CoveringLanes will be completely covered by
// another sub-register with the same or larger lane mask.
unsigned CoveringLanes;
};
}

View File

@ -1270,7 +1270,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable, 0x";
OS.write_hex(RegBank.CoveringLanes);
OS << ") {\n"
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
<< Regs.size()+1 << ", RA, PC,\n " << TargetName
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"