diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 98d39f7a89e..813a71ab3bd 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -529,6 +529,55 @@ CodeGenRegister::addSubRegsPreOrder(SetVector &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 Roots = RU.getRoots(); + for (unsigned ri = 0, re = Roots.size(); ri != re; ++ri) { + const CodeGenRegister *Root = Roots[ri]; + Overlaps.insert(Root); + ArrayRef 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 &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 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 e6c72df7407..d00b999aff7 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -189,6 +189,9 @@ namespace llvm { // Canonically ordered set. typedef std::set 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 &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 98bb611126e..a5e414ffeda 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 &Regs = RegBank.getRegisters(); - std::map 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),