summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-09-11 16:34:08 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-09-11 16:34:08 +0000
commita6035773d8d29827a124e65c258adbf0dcbb1a5a (patch)
tree7e96180d5cc189add9ff33b5753122d491968fd2 /utils
parentde0250728b1a9e69ca593168f1ea2ecef8e9bf95 (diff)
downloadllvm-a6035773d8d29827a124e65c258adbf0dcbb1a5a.tar.gz
llvm-a6035773d8d29827a124e65c258adbf0dcbb1a5a.tar.bz2
llvm-a6035773d8d29827a124e65c258adbf0dcbb1a5a.tar.xz
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
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp51
-rw-r--r--utils/TableGen/CodeGenRegisters.h7
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp16
3 files changed, 68 insertions, 6 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 78ea9ede76..931807ae44 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 72b6196038..bd748ca62e 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 80d4a6fede..42b213c04a 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"