summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-16 23:03:04 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-16 23:03:04 +0000
commit3778aeb74864390bf763424c45cc355ac330fbc9 (patch)
treec065591be602aa00be92acb640dcc3291376caf7
parent66e19c3e9db6e2727be21074a52f5c9fa187050f (diff)
downloadllvm-3778aeb74864390bf763424c45cc355ac330fbc9.tar.gz
llvm-3778aeb74864390bf763424c45cc355ac330fbc9.tar.bz2
llvm-3778aeb74864390bf763424c45cc355ac330fbc9.tar.xz
Use RegUnits to compute overlapping registers.
TableGen already computes register units as the basic unit of interference. We can use that to compute the set of overlapping registers. This means that we can easily compute overlap sets for one register at a time. There is no benefit to computing all registers at once. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156960 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp120
-rw-r--r--utils/TableGen/CodeGenRegisters.h12
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp5
3 files changed, 54 insertions, 83 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 98d39f7a89..813a71ab3b 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -529,6 +529,55 @@ CodeGenRegister::addSubRegsPreOrder(SetVector<const CodeGenRegister*> &OSet,
OSet.insert(I->second);
}
+// Compute overlapping registers.
+//
+// The standard set is all super-registers and all sub-registers, but the
+// target description can add arbitrary overlapping registers via the 'Aliases'
+// field. This complicates things, but we can compute overlapping sets using
+// the following rules:
+//
+// 1. The relation overlap(A, B) is reflexive and symmetric but not transitive.
+//
+// 2. overlap(A, B) implies overlap(A, S) for all S in supers(B).
+//
+// Alternatively:
+//
+// overlap(A, B) iff there exists:
+// A' in { A, subregs(A) } and B' in { B, subregs(B) } such that:
+// A' = B' or A' in aliases(B') or B' in aliases(A').
+//
+// Here subregs(A) is the full flattened sub-register set returned by
+// A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the
+// description of register A.
+//
+// This also implies that registers with a common sub-register are considered
+// overlapping. This can happen when forming register pairs:
+//
+// P0 = (R0, R1)
+// P1 = (R1, R2)
+// P2 = (R2, R3)
+//
+// In this case, we will infer an overlap between P0 and P1 because of the
+// shared sub-register R1. There is no overlap between P0 and P2.
+//
+void CodeGenRegister::computeOverlaps(CodeGenRegister::Set &Overlaps,
+ const CodeGenRegBank &RegBank) const {
+ assert(!RegUnits.empty() && "Compute register units before overlaps.");
+
+ // Register units are assigned such that the overlapping registers are the
+ // super-registers of the root registers of the register units.
+ for (unsigned rui = 0, rue = RegUnits.size(); rui != rue; ++rui) {
+ const RegUnit &RU = RegBank.getRegUnit(RegUnits[rui]);
+ ArrayRef<const CodeGenRegister*> Roots = RU.getRoots();
+ for (unsigned ri = 0, re = Roots.size(); ri != re; ++ri) {
+ const CodeGenRegister *Root = Roots[ri];
+ Overlaps.insert(Root);
+ ArrayRef<const CodeGenRegister*> Supers = Root->getSuperRegs();
+ Overlaps.insert(Supers.begin(), Supers.end());
+ }
+ }
+}
+
// Get the sum of this register's unit weights.
unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const {
unsigned Weight = 0;
@@ -1507,77 +1556,6 @@ void CodeGenRegBank::computeRegUnitSets() {
}
}
-// Compute sets of overlapping registers.
-//
-// The standard set is all super-registers and all sub-registers, but the
-// target description can add arbitrary overlapping registers via the 'Aliases'
-// field. This complicates things, but we can compute overlapping sets using
-// the following rules:
-//
-// 1. The relation overlap(A, B) is reflexive and symmetric but not transitive.
-//
-// 2. overlap(A, B) implies overlap(A, S) for all S in supers(B).
-//
-// Alternatively:
-//
-// overlap(A, B) iff there exists:
-// A' in { A, subregs(A) } and B' in { B, subregs(B) } such that:
-// A' = B' or A' in aliases(B') or B' in aliases(A').
-//
-// Here subregs(A) is the full flattened sub-register set returned by
-// A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the
-// description of register A.
-//
-// This also implies that registers with a common sub-register are considered
-// overlapping. This can happen when forming register pairs:
-//
-// P0 = (R0, R1)
-// P1 = (R1, R2)
-// P2 = (R2, R3)
-//
-// In this case, we will infer an overlap between P0 and P1 because of the
-// shared sub-register R1. There is no overlap between P0 and P2.
-//
-void CodeGenRegBank::
-computeOverlaps(std::map<const CodeGenRegister*, CodeGenRegister::Set> &Map) {
- assert(Map.empty());
-
- // Collect overlaps that don't follow from rule 2.
- for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
- CodeGenRegister *Reg = Registers[i];
- CodeGenRegister::Set &Overlaps = Map[Reg];
-
- // Reg overlaps itself.
- Overlaps.insert(Reg);
-
- // All super-registers overlap.
- const CodeGenRegister::SuperRegList &Supers = Reg->getSuperRegs();
- Overlaps.insert(Supers.begin(), Supers.end());
-
- // Form symmetrical relations from the special Aliases[] lists.
- ArrayRef<CodeGenRegister*> RegList = Reg->getExplicitAliases();
- for (unsigned i2 = 0, e2 = RegList.size(); i2 != e2; ++i2) {
- CodeGenRegister *Reg2 = RegList[i2];
- const CodeGenRegister::SuperRegList &Supers2 = Reg2->getSuperRegs();
- // Reg overlaps Reg2 which implies it overlaps supers(Reg2).
- Overlaps.insert(Reg2);
- Overlaps.insert(Supers2.begin(), Supers2.end());
- }
- }
-
- // Apply rule 2. and inherit all sub-register overlaps.
- for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
- CodeGenRegister *Reg = Registers[i];
- CodeGenRegister::Set &Overlaps = Map[Reg];
- const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs();
- for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM.begin(),
- e2 = SRM.end(); i2 != e2; ++i2) {
- CodeGenRegister::Set &Overlaps2 = Map[i2->second];
- Overlaps.insert(Overlaps2.begin(), Overlaps2.end());
- }
- }
-}
-
void CodeGenRegBank::computeDerivedInfo() {
computeComposites();
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index e6c72df740..d00b999aff 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -189,6 +189,9 @@ namespace llvm {
// Canonically ordered set.
typedef std::set<const CodeGenRegister*, Less> Set;
+ // Compute the set of registers overlapping this.
+ void computeOverlaps(Set &Overlaps, const CodeGenRegBank&) const;
+
private:
bool SubRegsComplete;
bool SuperRegsComplete;
@@ -601,15 +604,6 @@ namespace llvm {
// Computed derived records such as missing sub-register indices.
void computeDerivedInfo();
- // Compute full overlap sets for every register. These sets include the
- // rarely used aliases that are neither sub nor super-registers.
- //
- // Map[R1].count(R2) is reflexive and symmetric, but not transitive.
- //
- // If R1 is a sub-register of R2, Map[R1] is a subset of Map[R2].
- void computeOverlaps(std::map<const CodeGenRegister*,
- CodeGenRegister::Set> &Map);
-
// Compute the set of registers completely covered by the registers in Regs.
// The returned BitVector will have a bit set for each register in Regs,
// all sub-registers, and all super-registers that are covered by the
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 98bb611126..a5e414ffed 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -466,8 +466,6 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << "#undef GET_REGINFO_MC_DESC\n";
const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
- std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
- RegBank.computeOverlaps(Overlaps);
// The lists of sub-registers, super-registers, and overlaps all go in the
// same array. That allows us to share suffixes.
@@ -504,7 +502,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
Omit.insert(Reg);
// Any elements not in Suffix.
- const CodeGenRegister::Set &OSet = Overlaps[Reg];
+ CodeGenRegister::Set OSet;
+ Reg->computeOverlaps(OSet, RegBank);
std::set_difference(OSet.begin(), OSet.end(),
Omit.begin(), Omit.end(),
std::back_inserter(OverlapList),