diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 6b1e70bba11..82fccde8de8 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -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 { diff --git a/lib/CodeGen/TargetRegisterInfo.cpp b/lib/CodeGen/TargetRegisterInfo.cpp index 84b4bfc3322..4c21daf07a5 100644 --- a/lib/CodeGen/TargetRegisterInfo.cpp +++ b/lib/CodeGen/TargetRegisterInfo.cpp @@ -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() {} diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 993b8dba426..1fe08b84b89 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -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::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 { diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 4f2cc28d492..b56555dade6 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -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 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; }; } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 1b5d90b8bda..f519b21de06 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -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"