diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-09-11 16:34:08 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-09-11 16:34:08 +0000 |
commit | a6035773d8d29827a124e65c258adbf0dcbb1a5a (patch) | |
tree | 7e96180d5cc189add9ff33b5753122d491968fd2 | |
parent | de0250728b1a9e69ca593168f1ea2ecef8e9bf95 (diff) | |
download | external_llvm-a6035773d8d29827a124e65c258adbf0dcbb1a5a.zip external_llvm-a6035773d8d29827a124e65c258adbf0dcbb1a5a.tar.gz external_llvm-a6035773d8d29827a124e65c258adbf0dcbb1a5a.tar.bz2 |
Add TRI::getSubRegIndexLaneMask().
Sub-register lane masks are bitmasks that can be used to determine if
two sub-registers of a virtual register will overlap. For example, ARM's
ssub0 and ssub1 sub-register indices don't overlap each other, but both
overlap dsub0 and qsub0.
The lane masks will be accurate on most targets, but on targets that use
sub-register indexes in an irregular way, the masks may conservatively
report that two sub-register indices overlap when the eventually
allocated physregs don't.
Irregular register banks also mean that the bits in a lane mask can't be
mapped onto register units, but the concept is similar.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163630 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 31 | ||||
-rw-r--r-- | lib/Target/TargetRegisterInfo.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.cpp | 51 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 7 | ||||
-rw-r--r-- | utils/TableGen/RegisterInfoEmitter.cpp | 16 |
5 files changed, 102 insertions, 9 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index d6d5409..942ee44 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -221,13 +221,17 @@ public: private: const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. + // Pointer to array of lane masks, one per sub-reg index. + const unsigned *SubRegIndexLaneMasks; + regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses protected: TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, - const char *const *subregindexnames); + const char *const *SRINames, + const unsigned *SRILaneMasks); virtual ~TargetRegisterInfo(); public: @@ -332,6 +336,31 @@ public: return SubRegIndexNames[SubIdx-1]; } + /// getSubRegIndexLaneMask - Return a bitmask representing the parts of a + /// register that are covered by SubIdx. + /// + /// Lane masks for sub-register indices are similar to register units for + /// physical registers. The individual bits in a lane mask can't be assigned + /// any specific meaning. They can be used to check if two sub-register + /// indices overlap. + /// + /// If the target has a register such that: + /// + /// getSubReg(Reg, A) overlaps getSubReg(Reg, B) + /// + /// then: + /// + /// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0 + /// + /// The converse is not necessarily true. If two lane masks have a common + /// bit, the corresponding sub-registers may not overlap, but it can be + /// assumed that they usually will. + unsigned getSubRegIndexLaneMask(unsigned SubIdx) const { + // SubIdx == 0 is allowed, it has the lane mask ~0u. + assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index"); + return SubRegIndexLaneMasks[SubIdx]; + } + /// 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/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp index 2395f2b..be8b582 100644 --- a/lib/Target/TargetRegisterInfo.cpp +++ b/lib/Target/TargetRegisterInfo.cpp @@ -20,8 +20,10 @@ using namespace llvm; TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RCB, regclass_iterator RCE, - const char *const *subregindexnames) - : InfoDesc(ID), SubRegIndexNames(subregindexnames), + const char *const *SRINames, + const unsigned *SRILaneMasks) + : InfoDesc(ID), SubRegIndexNames(SRINames), + SubRegIndexLaneMasks(SRILaneMasks), RegClassBegin(RCB), RegClassEnd(RCE) { } diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 78ea9ed..931807a 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) { + : TheDef(R), EnumValue(Enum), LaneMask(0) { Name = R->getName(); if (R->getValue("Namespace")) Namespace = R->getValueAsString("Namespace"); @@ -36,7 +36,7 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum) - : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum) { + : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), LaneMask(0) { } std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -75,6 +75,23 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { } } +unsigned CodeGenSubRegIndex::computeLaneMask() { + // Already computed? + if (LaneMask) + return LaneMask; + + // Recursion guard, shouldn't be required. + LaneMask = ~0u; + + // The lane mask is simply the union of all sub-indices. + unsigned M = 0; + for (CompMap::iterator I = Composed.begin(), E = Composed.end(); I != E; ++I) + M |= I->second->computeLaneMask(); + assert(M && "Missing lane mask, sub-register cycle?"); + LaneMask = M; + return LaneMask; +} + //===----------------------------------------------------------------------===// // CodeGenRegister //===----------------------------------------------------------------------===// @@ -1156,6 +1173,35 @@ void CodeGenRegBank::computeComposites() { } } +// Compute lane masks. This is similar to register units, but at the +// sub-register index level. Each bit in the lane mask is like a register unit +// class, and two lane masks will have a bit in common if two sub-register +// indices overlap in some register. +// +// Conservatively share a lane mask bit if two sub-register indices overlap in +// some registers, but not in others. That shouldn't happen a lot. +void CodeGenRegBank::computeSubRegIndexLaneMasks() { + // First assign individual bits to all the leaf indices. + unsigned Bit = 0; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + CodeGenSubRegIndex *Idx = SubRegIndices[i]; + if (Idx->getComposites().empty()) { + Idx->LaneMask = 1u << Bit; + // Share bit 31 in the unlikely case there are more than 32 leafs. + if (Bit < 31) ++Bit; + } else { + Idx->LaneMask = 0; + } + } + + // FIXME: What if ad-hoc aliasing introduces overlaps that aren't represented + // 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(); +} + namespace { // UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is // the transitive closure of the union of overlapping register @@ -1539,6 +1585,7 @@ void CodeGenRegBank::computeRegUnitSets() { void CodeGenRegBank::computeDerivedInfo() { computeComposites(); + computeSubRegIndexLaneMasks(); // Compute a weight for each register unit created during getSubRegs. // This may create adopted register units (with unit # >= NumNativeRegUnits). diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 72b6196..bd748ca 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -40,6 +40,7 @@ namespace llvm { public: const unsigned EnumValue; + unsigned LaneMask; CodeGenSubRegIndex(Record *R, unsigned Enum); CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum); @@ -83,6 +84,9 @@ namespace llvm { // Return the map of composites. const CompMap &getComposites() const { return Composed; } + // Compute LaneMask from Composed. Return LaneMask. + unsigned computeLaneMask(); + private: CompMap Composed; }; @@ -486,6 +490,9 @@ namespace llvm { // Populate the Composite map from sub-register relationships. void computeComposites(); + // Compute a lane mask for each sub-register index. + void computeSubRegIndexLaneMasks(); + public: CodeGenRegBank(RecordKeeper&); diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 80d4a6f..42b213c 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -876,15 +876,23 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, VTSeqs.emit(OS, printSimpleValueType, "MVT::Other"); OS << "};\n"; - // Emit SubRegIndex names, skipping 0 - OS << "\nstatic const char *const SubRegIndexTable[] = { \""; + // Emit SubRegIndex names, skipping 0. + OS << "\nstatic const char *const SubRegIndexNameTable[] = { \""; for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { OS << SubRegIndices[i]->getName(); - if (i+1 != e) + if (i + 1 != e) OS << "\", \""; } OS << "\" };\n\n"; + // Emit SubRegIndex lane masks, including 0. + OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n"; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + OS << format(" 0x%08x, // ", SubRegIndices[i]->LaneMask) + << SubRegIndices[i]->getName() << '\n'; + } + OS << " };\n\n"; + OS << "\n"; // Now that all of the structs have been emitted, emit the instances. @@ -1122,7 +1130,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n" << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc" << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" - << " SubRegIndexTable) {\n" + << " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n" << " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA,\n " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" |