summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-05-16 18:03:08 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-05-16 18:03:08 +0000
commit997fa623fc14122153c58ddda8c90aa30f192cc8 (patch)
treec9417309d692437447d0ce7c29125b5733149b4c
parent347a5079e18278803bc05b197d325b8580e95610 (diff)
downloadllvm-997fa623fc14122153c58ddda8c90aa30f192cc8.tar.gz
llvm-997fa623fc14122153c58ddda8c90aa30f192cc8.tar.bz2
llvm-997fa623fc14122153c58ddda8c90aa30f192cc8.tar.xz
Add TargetRegisterInfo::getCoveringLanes().
This lane mask provides information about which register lanes completely cover super-registers. See the block comment before getCoveringLanes(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182034 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h29
-rw-r--r--lib/CodeGen/TargetRegisterInfo.cpp6
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp28
-rw-r--r--utils/TableGen/CodeGenRegisters.h9
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp4
5 files changed, 67 insertions, 9 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 6b1e70bba1..82fccde8de 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 84b4bfc332..4c21daf07a 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 993b8dba42..1fe08b84b8 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<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 {
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 4f2cc28d49..b56555dade 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<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;
};
}
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 1b5d90b8bd..f519b21de0 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"