10b57cec5SDimitry Andric //===- CodeGenRegisters.cpp - Register and RegisterClass Info -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines structures to encapsulate information gleaned from the
100b57cec5SDimitry Andric // target register and register class definitions.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "CodeGenRegisters.h"
150b57cec5SDimitry Andric #include "CodeGenTarget.h"
160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
170b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
190b57cec5SDimitry Andric #include "llvm/ADT/IntEqClasses.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
230b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
240b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
250b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
260b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
270b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
280b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
290b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
300b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
310b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
320b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
330b57cec5SDimitry Andric #include <algorithm>
340b57cec5SDimitry Andric #include <cassert>
350b57cec5SDimitry Andric #include <cstdint>
360b57cec5SDimitry Andric #include <iterator>
370b57cec5SDimitry Andric #include <map>
380b57cec5SDimitry Andric #include <queue>
390b57cec5SDimitry Andric #include <set>
400b57cec5SDimitry Andric #include <string>
410b57cec5SDimitry Andric #include <tuple>
420b57cec5SDimitry Andric #include <utility>
430b57cec5SDimitry Andric #include <vector>
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric using namespace llvm;
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric #define DEBUG_TYPE "regalloc-emitter"
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
500b57cec5SDimitry Andric // CodeGenSubRegIndex
510b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
520b57cec5SDimitry Andric
CodeGenSubRegIndex(Record * R,unsigned Enum)530b57cec5SDimitry Andric CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
540b57cec5SDimitry Andric : TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) {
555ffd83dbSDimitry Andric Name = std::string(R->getName());
560b57cec5SDimitry Andric if (R->getValue("Namespace"))
575ffd83dbSDimitry Andric Namespace = std::string(R->getValueAsString("Namespace"));
580b57cec5SDimitry Andric Size = R->getValueAsInt("Size");
590b57cec5SDimitry Andric Offset = R->getValueAsInt("Offset");
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric
CodeGenSubRegIndex(StringRef N,StringRef Nspace,unsigned Enum)620b57cec5SDimitry Andric CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
630b57cec5SDimitry Andric unsigned Enum)
645ffd83dbSDimitry Andric : TheDef(nullptr), Name(std::string(N)), Namespace(std::string(Nspace)),
655ffd83dbSDimitry Andric Size(-1), Offset(-1), EnumValue(Enum), AllSuperRegsCovered(true),
665ffd83dbSDimitry Andric Artificial(true) {}
670b57cec5SDimitry Andric
getQualifiedName() const680b57cec5SDimitry Andric std::string CodeGenSubRegIndex::getQualifiedName() const {
690b57cec5SDimitry Andric std::string N = getNamespace();
700b57cec5SDimitry Andric if (!N.empty())
710b57cec5SDimitry Andric N += "::";
720b57cec5SDimitry Andric N += getName();
730b57cec5SDimitry Andric return N;
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric
updateComponents(CodeGenRegBank & RegBank)760b57cec5SDimitry Andric void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
770b57cec5SDimitry Andric if (!TheDef)
780b57cec5SDimitry Andric return;
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric std::vector<Record*> Comps = TheDef->getValueAsListOfDefs("ComposedOf");
810b57cec5SDimitry Andric if (!Comps.empty()) {
820b57cec5SDimitry Andric if (Comps.size() != 2)
830b57cec5SDimitry Andric PrintFatalError(TheDef->getLoc(),
840b57cec5SDimitry Andric "ComposedOf must have exactly two entries");
850b57cec5SDimitry Andric CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]);
860b57cec5SDimitry Andric CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]);
870b57cec5SDimitry Andric CodeGenSubRegIndex *X = A->addComposite(B, this);
880b57cec5SDimitry Andric if (X)
890b57cec5SDimitry Andric PrintFatalError(TheDef->getLoc(), "Ambiguous ComposedOf entries");
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric std::vector<Record*> Parts =
930b57cec5SDimitry Andric TheDef->getValueAsListOfDefs("CoveringSubRegIndices");
940b57cec5SDimitry Andric if (!Parts.empty()) {
950b57cec5SDimitry Andric if (Parts.size() < 2)
960b57cec5SDimitry Andric PrintFatalError(TheDef->getLoc(),
970b57cec5SDimitry Andric "CoveredBySubRegs must have two or more entries");
980b57cec5SDimitry Andric SmallVector<CodeGenSubRegIndex*, 8> IdxParts;
990b57cec5SDimitry Andric for (Record *Part : Parts)
1000b57cec5SDimitry Andric IdxParts.push_back(RegBank.getSubRegIdx(Part));
1010b57cec5SDimitry Andric setConcatenationOf(IdxParts);
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric
computeLaneMask() const1050b57cec5SDimitry Andric LaneBitmask CodeGenSubRegIndex::computeLaneMask() const {
1060b57cec5SDimitry Andric // Already computed?
1070b57cec5SDimitry Andric if (LaneMask.any())
1080b57cec5SDimitry Andric return LaneMask;
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric // Recursion guard, shouldn't be required.
1110b57cec5SDimitry Andric LaneMask = LaneBitmask::getAll();
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric // The lane mask is simply the union of all sub-indices.
1140b57cec5SDimitry Andric LaneBitmask M;
1150b57cec5SDimitry Andric for (const auto &C : Composed)
1160b57cec5SDimitry Andric M |= C.second->computeLaneMask();
1170b57cec5SDimitry Andric assert(M.any() && "Missing lane mask, sub-register cycle?");
1180b57cec5SDimitry Andric LaneMask = M;
1190b57cec5SDimitry Andric return LaneMask;
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric
setConcatenationOf(ArrayRef<CodeGenSubRegIndex * > Parts)1220b57cec5SDimitry Andric void CodeGenSubRegIndex::setConcatenationOf(
1230b57cec5SDimitry Andric ArrayRef<CodeGenSubRegIndex*> Parts) {
1240b57cec5SDimitry Andric if (ConcatenationOf.empty())
1250b57cec5SDimitry Andric ConcatenationOf.assign(Parts.begin(), Parts.end());
1260b57cec5SDimitry Andric else
1270b57cec5SDimitry Andric assert(std::equal(Parts.begin(), Parts.end(),
1280b57cec5SDimitry Andric ConcatenationOf.begin()) && "parts consistent");
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric
computeConcatTransitiveClosure()1310b57cec5SDimitry Andric void CodeGenSubRegIndex::computeConcatTransitiveClosure() {
1320b57cec5SDimitry Andric for (SmallVectorImpl<CodeGenSubRegIndex*>::iterator
1330b57cec5SDimitry Andric I = ConcatenationOf.begin(); I != ConcatenationOf.end(); /*empty*/) {
1340b57cec5SDimitry Andric CodeGenSubRegIndex *SubIdx = *I;
1350b57cec5SDimitry Andric SubIdx->computeConcatTransitiveClosure();
1360b57cec5SDimitry Andric #ifndef NDEBUG
1370b57cec5SDimitry Andric for (CodeGenSubRegIndex *SRI : SubIdx->ConcatenationOf)
1380b57cec5SDimitry Andric assert(SRI->ConcatenationOf.empty() && "No transitive closure?");
1390b57cec5SDimitry Andric #endif
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric if (SubIdx->ConcatenationOf.empty()) {
1420b57cec5SDimitry Andric ++I;
1430b57cec5SDimitry Andric } else {
1440b57cec5SDimitry Andric I = ConcatenationOf.erase(I);
1450b57cec5SDimitry Andric I = ConcatenationOf.insert(I, SubIdx->ConcatenationOf.begin(),
1460b57cec5SDimitry Andric SubIdx->ConcatenationOf.end());
1470b57cec5SDimitry Andric I += SubIdx->ConcatenationOf.size();
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1530b57cec5SDimitry Andric // CodeGenRegister
1540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1550b57cec5SDimitry Andric
CodeGenRegister(Record * R,unsigned Enum)1560b57cec5SDimitry Andric CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum)
157*5f7ddb14SDimitry Andric : TheDef(R), EnumValue(Enum),
158*5f7ddb14SDimitry Andric CostPerUse(R->getValueAsListOfInts("CostPerUse")),
1590b57cec5SDimitry Andric CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
160*5f7ddb14SDimitry Andric HasDisjunctSubRegs(false), SubRegsComplete(false),
161*5f7ddb14SDimitry Andric SuperRegsComplete(false), TopoSig(~0u) {
1620b57cec5SDimitry Andric Artificial = R->getValueAsBit("isArtificial");
1630b57cec5SDimitry Andric }
1640b57cec5SDimitry Andric
buildObjectGraph(CodeGenRegBank & RegBank)1650b57cec5SDimitry Andric void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
1660b57cec5SDimitry Andric std::vector<Record*> SRIs = TheDef->getValueAsListOfDefs("SubRegIndices");
1670b57cec5SDimitry Andric std::vector<Record*> SRs = TheDef->getValueAsListOfDefs("SubRegs");
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric if (SRIs.size() != SRs.size())
1700b57cec5SDimitry Andric PrintFatalError(TheDef->getLoc(),
1710b57cec5SDimitry Andric "SubRegs and SubRegIndices must have the same size");
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric for (unsigned i = 0, e = SRIs.size(); i != e; ++i) {
1740b57cec5SDimitry Andric ExplicitSubRegIndices.push_back(RegBank.getSubRegIdx(SRIs[i]));
1750b57cec5SDimitry Andric ExplicitSubRegs.push_back(RegBank.getReg(SRs[i]));
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric // Also compute leading super-registers. Each register has a list of
1790b57cec5SDimitry Andric // covered-by-subregs super-registers where it appears as the first explicit
1800b57cec5SDimitry Andric // sub-register.
1810b57cec5SDimitry Andric //
1820b57cec5SDimitry Andric // This is used by computeSecondarySubRegs() to find candidates.
1830b57cec5SDimitry Andric if (CoveredBySubRegs && !ExplicitSubRegs.empty())
1840b57cec5SDimitry Andric ExplicitSubRegs.front()->LeadingSuperRegs.push_back(this);
1850b57cec5SDimitry Andric
1860b57cec5SDimitry Andric // Add ad hoc alias links. This is a symmetric relationship between two
1870b57cec5SDimitry Andric // registers, so build a symmetric graph by adding links in both ends.
1880b57cec5SDimitry Andric std::vector<Record*> Aliases = TheDef->getValueAsListOfDefs("Aliases");
1890b57cec5SDimitry Andric for (Record *Alias : Aliases) {
1900b57cec5SDimitry Andric CodeGenRegister *Reg = RegBank.getReg(Alias);
1910b57cec5SDimitry Andric ExplicitAliases.push_back(Reg);
1920b57cec5SDimitry Andric Reg->ExplicitAliases.push_back(this);
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric
getName() const196af732203SDimitry Andric StringRef CodeGenRegister::getName() const {
1970b57cec5SDimitry Andric assert(TheDef && "no def");
1980b57cec5SDimitry Andric return TheDef->getName();
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric namespace {
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric // Iterate over all register units in a set of registers.
2040b57cec5SDimitry Andric class RegUnitIterator {
2050b57cec5SDimitry Andric CodeGenRegister::Vec::const_iterator RegI, RegE;
2060b57cec5SDimitry Andric CodeGenRegister::RegUnitList::iterator UnitI, UnitE;
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric public:
RegUnitIterator(const CodeGenRegister::Vec & Regs)2090b57cec5SDimitry Andric RegUnitIterator(const CodeGenRegister::Vec &Regs):
2100b57cec5SDimitry Andric RegI(Regs.begin()), RegE(Regs.end()) {
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric if (RegI != RegE) {
2130b57cec5SDimitry Andric UnitI = (*RegI)->getRegUnits().begin();
2140b57cec5SDimitry Andric UnitE = (*RegI)->getRegUnits().end();
2150b57cec5SDimitry Andric advance();
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric
isValid() const2190b57cec5SDimitry Andric bool isValid() const { return UnitI != UnitE; }
2200b57cec5SDimitry Andric
operator *() const2210b57cec5SDimitry Andric unsigned operator* () const { assert(isValid()); return *UnitI; }
2220b57cec5SDimitry Andric
getReg() const2230b57cec5SDimitry Andric const CodeGenRegister *getReg() const { assert(isValid()); return *RegI; }
2240b57cec5SDimitry Andric
2250b57cec5SDimitry Andric /// Preincrement. Move to the next unit.
operator ++()2260b57cec5SDimitry Andric void operator++() {
2270b57cec5SDimitry Andric assert(isValid() && "Cannot advance beyond the last operand");
2280b57cec5SDimitry Andric ++UnitI;
2290b57cec5SDimitry Andric advance();
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric protected:
advance()2330b57cec5SDimitry Andric void advance() {
2340b57cec5SDimitry Andric while (UnitI == UnitE) {
2350b57cec5SDimitry Andric if (++RegI == RegE)
2360b57cec5SDimitry Andric break;
2370b57cec5SDimitry Andric UnitI = (*RegI)->getRegUnits().begin();
2380b57cec5SDimitry Andric UnitE = (*RegI)->getRegUnits().end();
2390b57cec5SDimitry Andric }
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric };
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric } // end anonymous namespace
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric // Return true of this unit appears in RegUnits.
hasRegUnit(CodeGenRegister::RegUnitList & RegUnits,unsigned Unit)2460b57cec5SDimitry Andric static bool hasRegUnit(CodeGenRegister::RegUnitList &RegUnits, unsigned Unit) {
2470b57cec5SDimitry Andric return RegUnits.test(Unit);
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric // Inherit register units from subregisters.
2510b57cec5SDimitry Andric // Return true if the RegUnits changed.
inheritRegUnits(CodeGenRegBank & RegBank)2520b57cec5SDimitry Andric bool CodeGenRegister::inheritRegUnits(CodeGenRegBank &RegBank) {
2530b57cec5SDimitry Andric bool changed = false;
2540b57cec5SDimitry Andric for (const auto &SubReg : SubRegs) {
2550b57cec5SDimitry Andric CodeGenRegister *SR = SubReg.second;
2560b57cec5SDimitry Andric // Merge the subregister's units into this register's RegUnits.
2570b57cec5SDimitry Andric changed |= (RegUnits |= SR->RegUnits);
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric return changed;
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &
computeSubRegs(CodeGenRegBank & RegBank)2640b57cec5SDimitry Andric CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
2650b57cec5SDimitry Andric // Only compute this map once.
2660b57cec5SDimitry Andric if (SubRegsComplete)
2670b57cec5SDimitry Andric return SubRegs;
2680b57cec5SDimitry Andric SubRegsComplete = true;
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andric HasDisjunctSubRegs = ExplicitSubRegs.size() > 1;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric // First insert the explicit subregs and make sure they are fully indexed.
2730b57cec5SDimitry Andric for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) {
2740b57cec5SDimitry Andric CodeGenRegister *SR = ExplicitSubRegs[i];
2750b57cec5SDimitry Andric CodeGenSubRegIndex *Idx = ExplicitSubRegIndices[i];
2760b57cec5SDimitry Andric if (!SR->Artificial)
2770b57cec5SDimitry Andric Idx->Artificial = false;
2780b57cec5SDimitry Andric if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
2790b57cec5SDimitry Andric PrintFatalError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
2800b57cec5SDimitry Andric " appears twice in Register " + getName());
2810b57cec5SDimitry Andric // Map explicit sub-registers first, so the names take precedence.
2820b57cec5SDimitry Andric // The inherited sub-registers are mapped below.
2830b57cec5SDimitry Andric SubReg2Idx.insert(std::make_pair(SR, Idx));
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric // Keep track of inherited subregs and how they can be reached.
2870b57cec5SDimitry Andric SmallPtrSet<CodeGenRegister*, 8> Orphans;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andric // Clone inherited subregs and place duplicate entries in Orphans.
2900b57cec5SDimitry Andric // Here the order is important - earlier subregs take precedence.
2910b57cec5SDimitry Andric for (CodeGenRegister *ESR : ExplicitSubRegs) {
2920b57cec5SDimitry Andric const SubRegMap &Map = ESR->computeSubRegs(RegBank);
2930b57cec5SDimitry Andric HasDisjunctSubRegs |= ESR->HasDisjunctSubRegs;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric for (const auto &SR : Map) {
2960b57cec5SDimitry Andric if (!SubRegs.insert(SR).second)
2970b57cec5SDimitry Andric Orphans.insert(SR.second);
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric // Expand any composed subreg indices.
3020b57cec5SDimitry Andric // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
3030b57cec5SDimitry Andric // qsub_1 subreg, add a dsub_2 subreg. Keep growing Indices and process
3040b57cec5SDimitry Andric // expanded subreg indices recursively.
3050b57cec5SDimitry Andric SmallVector<CodeGenSubRegIndex*, 8> Indices = ExplicitSubRegIndices;
3060b57cec5SDimitry Andric for (unsigned i = 0; i != Indices.size(); ++i) {
3070b57cec5SDimitry Andric CodeGenSubRegIndex *Idx = Indices[i];
3080b57cec5SDimitry Andric const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
3090b57cec5SDimitry Andric CodeGenRegister *SR = SubRegs[Idx];
3100b57cec5SDimitry Andric const SubRegMap &Map = SR->computeSubRegs(RegBank);
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric // Look at the possible compositions of Idx.
3130b57cec5SDimitry Andric // They may not all be supported by SR.
314*5f7ddb14SDimitry Andric for (auto Comp : Comps) {
315*5f7ddb14SDimitry Andric SubRegMap::const_iterator SRI = Map.find(Comp.first);
3160b57cec5SDimitry Andric if (SRI == Map.end())
3170b57cec5SDimitry Andric continue; // Idx + I->first doesn't exist in SR.
3180b57cec5SDimitry Andric // Add I->second as a name for the subreg SRI->second, assuming it is
3190b57cec5SDimitry Andric // orphaned, and the name isn't already used for something else.
320*5f7ddb14SDimitry Andric if (SubRegs.count(Comp.second) || !Orphans.erase(SRI->second))
3210b57cec5SDimitry Andric continue;
3220b57cec5SDimitry Andric // We found a new name for the orphaned sub-register.
323*5f7ddb14SDimitry Andric SubRegs.insert(std::make_pair(Comp.second, SRI->second));
324*5f7ddb14SDimitry Andric Indices.push_back(Comp.second);
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric }
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric // Now Orphans contains the inherited subregisters without a direct index.
3290b57cec5SDimitry Andric // Create inferred indexes for all missing entries.
3300b57cec5SDimitry Andric // Work backwards in the Indices vector in order to compose subregs bottom-up.
3310b57cec5SDimitry Andric // Consider this subreg sequence:
3320b57cec5SDimitry Andric //
3330b57cec5SDimitry Andric // qsub_1 -> dsub_0 -> ssub_0
3340b57cec5SDimitry Andric //
3350b57cec5SDimitry Andric // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register
3360b57cec5SDimitry Andric // can be reached in two different ways:
3370b57cec5SDimitry Andric //
3380b57cec5SDimitry Andric // qsub_1 -> ssub_0
3390b57cec5SDimitry Andric // dsub_2 -> ssub_0
3400b57cec5SDimitry Andric //
3410b57cec5SDimitry Andric // We pick the latter composition because another register may have [dsub_0,
3420b57cec5SDimitry Andric // dsub_1, dsub_2] subregs without necessarily having a qsub_1 subreg. The
3430b57cec5SDimitry Andric // dsub_2 -> ssub_0 composition can be shared.
3440b57cec5SDimitry Andric while (!Indices.empty() && !Orphans.empty()) {
3450b57cec5SDimitry Andric CodeGenSubRegIndex *Idx = Indices.pop_back_val();
3460b57cec5SDimitry Andric CodeGenRegister *SR = SubRegs[Idx];
3470b57cec5SDimitry Andric const SubRegMap &Map = SR->computeSubRegs(RegBank);
3480b57cec5SDimitry Andric for (const auto &SubReg : Map)
3490b57cec5SDimitry Andric if (Orphans.erase(SubReg.second))
3500b57cec5SDimitry Andric SubRegs[RegBank.getCompositeSubRegIndex(Idx, SubReg.first)] = SubReg.second;
3510b57cec5SDimitry Andric }
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andric // Compute the inverse SubReg -> Idx map.
3540b57cec5SDimitry Andric for (const auto &SubReg : SubRegs) {
3550b57cec5SDimitry Andric if (SubReg.second == this) {
3560b57cec5SDimitry Andric ArrayRef<SMLoc> Loc;
3570b57cec5SDimitry Andric if (TheDef)
3580b57cec5SDimitry Andric Loc = TheDef->getLoc();
3590b57cec5SDimitry Andric PrintFatalError(Loc, "Register " + getName() +
3600b57cec5SDimitry Andric " has itself as a sub-register");
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric // Compute AllSuperRegsCovered.
3640b57cec5SDimitry Andric if (!CoveredBySubRegs)
3650b57cec5SDimitry Andric SubReg.first->AllSuperRegsCovered = false;
3660b57cec5SDimitry Andric
3670b57cec5SDimitry Andric // Ensure that every sub-register has a unique name.
3680b57cec5SDimitry Andric DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*>::iterator Ins =
3690b57cec5SDimitry Andric SubReg2Idx.insert(std::make_pair(SubReg.second, SubReg.first)).first;
3700b57cec5SDimitry Andric if (Ins->second == SubReg.first)
3710b57cec5SDimitry Andric continue;
3720b57cec5SDimitry Andric // Trouble: Two different names for SubReg.second.
3730b57cec5SDimitry Andric ArrayRef<SMLoc> Loc;
3740b57cec5SDimitry Andric if (TheDef)
3750b57cec5SDimitry Andric Loc = TheDef->getLoc();
3760b57cec5SDimitry Andric PrintFatalError(Loc, "Sub-register can't have two names: " +
3770b57cec5SDimitry Andric SubReg.second->getName() + " available as " +
3780b57cec5SDimitry Andric SubReg.first->getName() + " and " + Ins->second->getName());
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric // Derive possible names for sub-register concatenations from any explicit
3820b57cec5SDimitry Andric // sub-registers. By doing this before computeSecondarySubRegs(), we ensure
3830b57cec5SDimitry Andric // that getConcatSubRegIndex() won't invent any concatenated indices that the
3840b57cec5SDimitry Andric // user already specified.
3850b57cec5SDimitry Andric for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) {
3860b57cec5SDimitry Andric CodeGenRegister *SR = ExplicitSubRegs[i];
3870b57cec5SDimitry Andric if (!SR->CoveredBySubRegs || SR->ExplicitSubRegs.size() <= 1 ||
3880b57cec5SDimitry Andric SR->Artificial)
3890b57cec5SDimitry Andric continue;
3900b57cec5SDimitry Andric
3910b57cec5SDimitry Andric // SR is composed of multiple sub-regs. Find their names in this register.
3920b57cec5SDimitry Andric SmallVector<CodeGenSubRegIndex*, 8> Parts;
3930b57cec5SDimitry Andric for (unsigned j = 0, e = SR->ExplicitSubRegs.size(); j != e; ++j) {
3940b57cec5SDimitry Andric CodeGenSubRegIndex &I = *SR->ExplicitSubRegIndices[j];
3950b57cec5SDimitry Andric if (!I.Artificial)
3960b57cec5SDimitry Andric Parts.push_back(getSubRegIndex(SR->ExplicitSubRegs[j]));
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric // Offer this as an existing spelling for the concatenation of Parts.
4000b57cec5SDimitry Andric CodeGenSubRegIndex &Idx = *ExplicitSubRegIndices[i];
4010b57cec5SDimitry Andric Idx.setConcatenationOf(Parts);
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric // Initialize RegUnitList. Because getSubRegs is called recursively, this
4050b57cec5SDimitry Andric // processes the register hierarchy in postorder.
4060b57cec5SDimitry Andric //
4070b57cec5SDimitry Andric // Inherit all sub-register units. It is good enough to look at the explicit
4080b57cec5SDimitry Andric // sub-registers, the other registers won't contribute any more units.
4090b57cec5SDimitry Andric for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) {
4100b57cec5SDimitry Andric CodeGenRegister *SR = ExplicitSubRegs[i];
4110b57cec5SDimitry Andric RegUnits |= SR->RegUnits;
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric // Absent any ad hoc aliasing, we create one register unit per leaf register.
4150b57cec5SDimitry Andric // These units correspond to the maximal cliques in the register overlap
4160b57cec5SDimitry Andric // graph which is optimal.
4170b57cec5SDimitry Andric //
4180b57cec5SDimitry Andric // When there is ad hoc aliasing, we simply create one unit per edge in the
4190b57cec5SDimitry Andric // undirected ad hoc aliasing graph. Technically, we could do better by
4200b57cec5SDimitry Andric // identifying maximal cliques in the ad hoc graph, but cliques larger than 2
4210b57cec5SDimitry Andric // are extremely rare anyway (I've never seen one), so we don't bother with
4220b57cec5SDimitry Andric // the added complexity.
4230b57cec5SDimitry Andric for (unsigned i = 0, e = ExplicitAliases.size(); i != e; ++i) {
4240b57cec5SDimitry Andric CodeGenRegister *AR = ExplicitAliases[i];
4250b57cec5SDimitry Andric // Only visit each edge once.
4260b57cec5SDimitry Andric if (AR->SubRegsComplete)
4270b57cec5SDimitry Andric continue;
4280b57cec5SDimitry Andric // Create a RegUnit representing this alias edge, and add it to both
4290b57cec5SDimitry Andric // registers.
4300b57cec5SDimitry Andric unsigned Unit = RegBank.newRegUnit(this, AR);
4310b57cec5SDimitry Andric RegUnits.set(Unit);
4320b57cec5SDimitry Andric AR->RegUnits.set(Unit);
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andric // Finally, create units for leaf registers without ad hoc aliases. Note that
4360b57cec5SDimitry Andric // a leaf register with ad hoc aliases doesn't get its own unit - it isn't
4370b57cec5SDimitry Andric // necessary. This means the aliasing leaf registers can share a single unit.
4380b57cec5SDimitry Andric if (RegUnits.empty())
4390b57cec5SDimitry Andric RegUnits.set(RegBank.newRegUnit(this));
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric // We have now computed the native register units. More may be adopted later
4420b57cec5SDimitry Andric // for balancing purposes.
4430b57cec5SDimitry Andric NativeRegUnits = RegUnits;
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric return SubRegs;
4460b57cec5SDimitry Andric }
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andric // In a register that is covered by its sub-registers, try to find redundant
4490b57cec5SDimitry Andric // sub-registers. For example:
4500b57cec5SDimitry Andric //
4510b57cec5SDimitry Andric // QQ0 = {Q0, Q1}
4520b57cec5SDimitry Andric // Q0 = {D0, D1}
4530b57cec5SDimitry Andric // Q1 = {D2, D3}
4540b57cec5SDimitry Andric //
4550b57cec5SDimitry Andric // We can infer that D1_D2 is also a sub-register, even if it wasn't named in
4560b57cec5SDimitry Andric // the register definition.
4570b57cec5SDimitry Andric //
4580b57cec5SDimitry Andric // The explicitly specified registers form a tree. This function discovers
4590b57cec5SDimitry Andric // sub-register relationships that would force a DAG.
4600b57cec5SDimitry Andric //
computeSecondarySubRegs(CodeGenRegBank & RegBank)4610b57cec5SDimitry Andric void CodeGenRegister::computeSecondarySubRegs(CodeGenRegBank &RegBank) {
4620b57cec5SDimitry Andric SmallVector<SubRegMap::value_type, 8> NewSubRegs;
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andric std::queue<std::pair<CodeGenSubRegIndex*,CodeGenRegister*>> SubRegQueue;
4650b57cec5SDimitry Andric for (std::pair<CodeGenSubRegIndex*,CodeGenRegister*> P : SubRegs)
4660b57cec5SDimitry Andric SubRegQueue.push(P);
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andric // Look at the leading super-registers of each sub-register. Those are the
4690b57cec5SDimitry Andric // candidates for new sub-registers, assuming they are fully contained in
4700b57cec5SDimitry Andric // this register.
4710b57cec5SDimitry Andric while (!SubRegQueue.empty()) {
4720b57cec5SDimitry Andric CodeGenSubRegIndex *SubRegIdx;
4730b57cec5SDimitry Andric const CodeGenRegister *SubReg;
4740b57cec5SDimitry Andric std::tie(SubRegIdx, SubReg) = SubRegQueue.front();
4750b57cec5SDimitry Andric SubRegQueue.pop();
4760b57cec5SDimitry Andric
4770b57cec5SDimitry Andric const CodeGenRegister::SuperRegList &Leads = SubReg->LeadingSuperRegs;
4780b57cec5SDimitry Andric for (unsigned i = 0, e = Leads.size(); i != e; ++i) {
4790b57cec5SDimitry Andric CodeGenRegister *Cand = const_cast<CodeGenRegister*>(Leads[i]);
4800b57cec5SDimitry Andric // Already got this sub-register?
4810b57cec5SDimitry Andric if (Cand == this || getSubRegIndex(Cand))
4820b57cec5SDimitry Andric continue;
4830b57cec5SDimitry Andric // Check if each component of Cand is already a sub-register.
4840b57cec5SDimitry Andric assert(!Cand->ExplicitSubRegs.empty() &&
4850b57cec5SDimitry Andric "Super-register has no sub-registers");
4860b57cec5SDimitry Andric if (Cand->ExplicitSubRegs.size() == 1)
4870b57cec5SDimitry Andric continue;
4880b57cec5SDimitry Andric SmallVector<CodeGenSubRegIndex*, 8> Parts;
4890b57cec5SDimitry Andric // We know that the first component is (SubRegIdx,SubReg). However we
4900b57cec5SDimitry Andric // may still need to split it into smaller subregister parts.
4910b57cec5SDimitry Andric assert(Cand->ExplicitSubRegs[0] == SubReg && "LeadingSuperRegs correct");
4920b57cec5SDimitry Andric assert(getSubRegIndex(SubReg) == SubRegIdx && "LeadingSuperRegs correct");
4930b57cec5SDimitry Andric for (CodeGenRegister *SubReg : Cand->ExplicitSubRegs) {
4940b57cec5SDimitry Andric if (CodeGenSubRegIndex *SubRegIdx = getSubRegIndex(SubReg)) {
495af732203SDimitry Andric if (SubRegIdx->ConcatenationOf.empty())
4960b57cec5SDimitry Andric Parts.push_back(SubRegIdx);
497af732203SDimitry Andric else
498af732203SDimitry Andric append_range(Parts, SubRegIdx->ConcatenationOf);
4990b57cec5SDimitry Andric } else {
5000b57cec5SDimitry Andric // Sub-register doesn't exist.
5010b57cec5SDimitry Andric Parts.clear();
5020b57cec5SDimitry Andric break;
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric // There is nothing to do if some Cand sub-register is not part of this
5060b57cec5SDimitry Andric // register.
5070b57cec5SDimitry Andric if (Parts.empty())
5080b57cec5SDimitry Andric continue;
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric // Each part of Cand is a sub-register of this. Make the full Cand also
5110b57cec5SDimitry Andric // a sub-register with a concatenated sub-register index.
5120b57cec5SDimitry Andric CodeGenSubRegIndex *Concat = RegBank.getConcatSubRegIndex(Parts);
5130b57cec5SDimitry Andric std::pair<CodeGenSubRegIndex*,CodeGenRegister*> NewSubReg =
5140b57cec5SDimitry Andric std::make_pair(Concat, Cand);
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andric if (!SubRegs.insert(NewSubReg).second)
5170b57cec5SDimitry Andric continue;
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andric // We inserted a new subregister.
5200b57cec5SDimitry Andric NewSubRegs.push_back(NewSubReg);
5210b57cec5SDimitry Andric SubRegQueue.push(NewSubReg);
5220b57cec5SDimitry Andric SubReg2Idx.insert(std::make_pair(Cand, Concat));
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric
5260b57cec5SDimitry Andric // Create sub-register index composition maps for the synthesized indices.
5270b57cec5SDimitry Andric for (unsigned i = 0, e = NewSubRegs.size(); i != e; ++i) {
5280b57cec5SDimitry Andric CodeGenSubRegIndex *NewIdx = NewSubRegs[i].first;
5290b57cec5SDimitry Andric CodeGenRegister *NewSubReg = NewSubRegs[i].second;
530*5f7ddb14SDimitry Andric for (auto SubReg : NewSubReg->SubRegs) {
531*5f7ddb14SDimitry Andric CodeGenSubRegIndex *SubIdx = getSubRegIndex(SubReg.second);
5320b57cec5SDimitry Andric if (!SubIdx)
5330b57cec5SDimitry Andric PrintFatalError(TheDef->getLoc(), "No SubRegIndex for " +
534*5f7ddb14SDimitry Andric SubReg.second->getName() +
535*5f7ddb14SDimitry Andric " in " + getName());
536*5f7ddb14SDimitry Andric NewIdx->addComposite(SubReg.first, SubIdx);
5370b57cec5SDimitry Andric }
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric
computeSuperRegs(CodeGenRegBank & RegBank)5410b57cec5SDimitry Andric void CodeGenRegister::computeSuperRegs(CodeGenRegBank &RegBank) {
5420b57cec5SDimitry Andric // Only visit each register once.
5430b57cec5SDimitry Andric if (SuperRegsComplete)
5440b57cec5SDimitry Andric return;
5450b57cec5SDimitry Andric SuperRegsComplete = true;
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric // Make sure all sub-registers have been visited first, so the super-reg
5480b57cec5SDimitry Andric // lists will be topologically ordered.
549*5f7ddb14SDimitry Andric for (auto SubReg : SubRegs)
550*5f7ddb14SDimitry Andric SubReg.second->computeSuperRegs(RegBank);
5510b57cec5SDimitry Andric
5520b57cec5SDimitry Andric // Now add this as a super-register on all sub-registers.
5530b57cec5SDimitry Andric // Also compute the TopoSigId in post-order.
5540b57cec5SDimitry Andric TopoSigId Id;
555*5f7ddb14SDimitry Andric for (auto SubReg : SubRegs) {
5560b57cec5SDimitry Andric // Topological signature computed from SubIdx, TopoId(SubReg).
5570b57cec5SDimitry Andric // Loops and idempotent indices have TopoSig = ~0u.
558*5f7ddb14SDimitry Andric Id.push_back(SubReg.first->EnumValue);
559*5f7ddb14SDimitry Andric Id.push_back(SubReg.second->TopoSig);
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andric // Don't add duplicate entries.
562*5f7ddb14SDimitry Andric if (!SubReg.second->SuperRegs.empty() &&
563*5f7ddb14SDimitry Andric SubReg.second->SuperRegs.back() == this)
5640b57cec5SDimitry Andric continue;
565*5f7ddb14SDimitry Andric SubReg.second->SuperRegs.push_back(this);
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric TopoSig = RegBank.getTopoSig(Id);
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andric void
addSubRegsPreOrder(SetVector<const CodeGenRegister * > & OSet,CodeGenRegBank & RegBank) const5710b57cec5SDimitry Andric CodeGenRegister::addSubRegsPreOrder(SetVector<const CodeGenRegister*> &OSet,
5720b57cec5SDimitry Andric CodeGenRegBank &RegBank) const {
5730b57cec5SDimitry Andric assert(SubRegsComplete && "Must precompute sub-registers");
5740b57cec5SDimitry Andric for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) {
5750b57cec5SDimitry Andric CodeGenRegister *SR = ExplicitSubRegs[i];
5760b57cec5SDimitry Andric if (OSet.insert(SR))
5770b57cec5SDimitry Andric SR->addSubRegsPreOrder(OSet, RegBank);
5780b57cec5SDimitry Andric }
5790b57cec5SDimitry Andric // Add any secondary sub-registers that weren't part of the explicit tree.
580*5f7ddb14SDimitry Andric for (auto SubReg : SubRegs)
581*5f7ddb14SDimitry Andric OSet.insert(SubReg.second);
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric
5840b57cec5SDimitry Andric // Get the sum of this register's unit weights.
getWeight(const CodeGenRegBank & RegBank) const5850b57cec5SDimitry Andric unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const {
5860b57cec5SDimitry Andric unsigned Weight = 0;
587*5f7ddb14SDimitry Andric for (unsigned RegUnit : RegUnits) {
588*5f7ddb14SDimitry Andric Weight += RegBank.getRegUnit(RegUnit).Weight;
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric return Weight;
5910b57cec5SDimitry Andric }
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5940b57cec5SDimitry Andric // RegisterTuples
5950b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric // A RegisterTuples def is used to generate pseudo-registers from lists of
5980b57cec5SDimitry Andric // sub-registers. We provide a SetTheory expander class that returns the new
5990b57cec5SDimitry Andric // registers.
6000b57cec5SDimitry Andric namespace {
6010b57cec5SDimitry Andric
6020b57cec5SDimitry Andric struct TupleExpander : SetTheory::Expander {
6030b57cec5SDimitry Andric // Reference to SynthDefs in the containing CodeGenRegBank, to keep track of
6040b57cec5SDimitry Andric // the synthesized definitions for their lifetime.
6050b57cec5SDimitry Andric std::vector<std::unique_ptr<Record>> &SynthDefs;
6060b57cec5SDimitry Andric
TupleExpander__anon29b8b01c0211::TupleExpander6070b57cec5SDimitry Andric TupleExpander(std::vector<std::unique_ptr<Record>> &SynthDefs)
6080b57cec5SDimitry Andric : SynthDefs(SynthDefs) {}
6090b57cec5SDimitry Andric
expand__anon29b8b01c0211::TupleExpander6100b57cec5SDimitry Andric void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) override {
6110b57cec5SDimitry Andric std::vector<Record*> Indices = Def->getValueAsListOfDefs("SubRegIndices");
6120b57cec5SDimitry Andric unsigned Dim = Indices.size();
6130b57cec5SDimitry Andric ListInit *SubRegs = Def->getValueAsListInit("SubRegs");
6140b57cec5SDimitry Andric if (Dim != SubRegs->size())
6150b57cec5SDimitry Andric PrintFatalError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch");
6160b57cec5SDimitry Andric if (Dim < 2)
6170b57cec5SDimitry Andric PrintFatalError(Def->getLoc(),
6180b57cec5SDimitry Andric "Tuples must have at least 2 sub-registers");
6190b57cec5SDimitry Andric
6200b57cec5SDimitry Andric // Evaluate the sub-register lists to be zipped.
6210b57cec5SDimitry Andric unsigned Length = ~0u;
6220b57cec5SDimitry Andric SmallVector<SetTheory::RecSet, 4> Lists(Dim);
6230b57cec5SDimitry Andric for (unsigned i = 0; i != Dim; ++i) {
6240b57cec5SDimitry Andric ST.evaluate(SubRegs->getElement(i), Lists[i], Def->getLoc());
6250b57cec5SDimitry Andric Length = std::min(Length, unsigned(Lists[i].size()));
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric
6280b57cec5SDimitry Andric if (Length == 0)
6290b57cec5SDimitry Andric return;
6300b57cec5SDimitry Andric
6310b57cec5SDimitry Andric // Precompute some types.
6320b57cec5SDimitry Andric Record *RegisterCl = Def->getRecords().getClass("Register");
6330b57cec5SDimitry Andric RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl);
6348bcb0991SDimitry Andric std::vector<StringRef> RegNames =
6358bcb0991SDimitry Andric Def->getValueAsListOfStrings("RegAsmNames");
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andric // Zip them up.
6380b57cec5SDimitry Andric for (unsigned n = 0; n != Length; ++n) {
6390b57cec5SDimitry Andric std::string Name;
6400b57cec5SDimitry Andric Record *Proto = Lists[0][n];
6410b57cec5SDimitry Andric std::vector<Init*> Tuple;
6420b57cec5SDimitry Andric for (unsigned i = 0; i != Dim; ++i) {
6430b57cec5SDimitry Andric Record *Reg = Lists[i][n];
6440b57cec5SDimitry Andric if (i) Name += '_';
6450b57cec5SDimitry Andric Name += Reg->getName();
6460b57cec5SDimitry Andric Tuple.push_back(DefInit::get(Reg));
6470b57cec5SDimitry Andric }
6480b57cec5SDimitry Andric
649*5f7ddb14SDimitry Andric // Take the cost list of the first register in the tuple.
650*5f7ddb14SDimitry Andric ListInit *CostList = Proto->getValueAsListInit("CostPerUse");
651*5f7ddb14SDimitry Andric SmallVector<Init *, 2> CostPerUse;
652*5f7ddb14SDimitry Andric CostPerUse.insert(CostPerUse.end(), CostList->begin(), CostList->end());
653*5f7ddb14SDimitry Andric
6548bcb0991SDimitry Andric StringInit *AsmName = StringInit::get("");
6558bcb0991SDimitry Andric if (!RegNames.empty()) {
6568bcb0991SDimitry Andric if (RegNames.size() <= n)
6578bcb0991SDimitry Andric PrintFatalError(Def->getLoc(),
6588bcb0991SDimitry Andric "Register tuple definition missing name for '" +
6598bcb0991SDimitry Andric Name + "'.");
6608bcb0991SDimitry Andric AsmName = StringInit::get(RegNames[n]);
6618bcb0991SDimitry Andric }
6628bcb0991SDimitry Andric
6630b57cec5SDimitry Andric // Create a new Record representing the synthesized register. This record
6640b57cec5SDimitry Andric // is only for consumption by CodeGenRegister, it is not added to the
6650b57cec5SDimitry Andric // RecordKeeper.
6660b57cec5SDimitry Andric SynthDefs.emplace_back(
6678bcb0991SDimitry Andric std::make_unique<Record>(Name, Def->getLoc(), Def->getRecords()));
6680b57cec5SDimitry Andric Record *NewReg = SynthDefs.back().get();
6690b57cec5SDimitry Andric Elts.insert(NewReg);
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andric // Copy Proto super-classes.
6720b57cec5SDimitry Andric ArrayRef<std::pair<Record *, SMRange>> Supers = Proto->getSuperClasses();
6730b57cec5SDimitry Andric for (const auto &SuperPair : Supers)
6740b57cec5SDimitry Andric NewReg->addSuperClass(SuperPair.first, SuperPair.second);
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andric // Copy Proto fields.
6770b57cec5SDimitry Andric for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
6780b57cec5SDimitry Andric RecordVal RV = Proto->getValues()[i];
6790b57cec5SDimitry Andric
6800b57cec5SDimitry Andric // Skip existing fields, like NAME.
6810b57cec5SDimitry Andric if (NewReg->getValue(RV.getNameInit()))
6820b57cec5SDimitry Andric continue;
6830b57cec5SDimitry Andric
6840b57cec5SDimitry Andric StringRef Field = RV.getName();
6850b57cec5SDimitry Andric
6860b57cec5SDimitry Andric // Replace the sub-register list with Tuple.
6870b57cec5SDimitry Andric if (Field == "SubRegs")
6880b57cec5SDimitry Andric RV.setValue(ListInit::get(Tuple, RegisterRecTy));
6890b57cec5SDimitry Andric
6900b57cec5SDimitry Andric if (Field == "AsmName")
6918bcb0991SDimitry Andric RV.setValue(AsmName);
6920b57cec5SDimitry Andric
6930b57cec5SDimitry Andric // CostPerUse is aggregated from all Tuple members.
6940b57cec5SDimitry Andric if (Field == "CostPerUse")
695*5f7ddb14SDimitry Andric RV.setValue(ListInit::get(CostPerUse, CostList->getElementType()));
6960b57cec5SDimitry Andric
6970b57cec5SDimitry Andric // Composite registers are always covered by sub-registers.
6980b57cec5SDimitry Andric if (Field == "CoveredBySubRegs")
6990b57cec5SDimitry Andric RV.setValue(BitInit::get(true));
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andric // Copy fields from the RegisterTuples def.
7020b57cec5SDimitry Andric if (Field == "SubRegIndices" ||
7030b57cec5SDimitry Andric Field == "CompositeIndices") {
7040b57cec5SDimitry Andric NewReg->addValue(*Def->getValue(Field));
7050b57cec5SDimitry Andric continue;
7060b57cec5SDimitry Andric }
7070b57cec5SDimitry Andric
7080b57cec5SDimitry Andric // Some fields get their default uninitialized value.
7090b57cec5SDimitry Andric if (Field == "DwarfNumbers" ||
7100b57cec5SDimitry Andric Field == "DwarfAlias" ||
7110b57cec5SDimitry Andric Field == "Aliases") {
7120b57cec5SDimitry Andric if (const RecordVal *DefRV = RegisterCl->getValue(Field))
7130b57cec5SDimitry Andric NewReg->addValue(*DefRV);
7140b57cec5SDimitry Andric continue;
7150b57cec5SDimitry Andric }
7160b57cec5SDimitry Andric
7170b57cec5SDimitry Andric // Everything else is copied from Proto.
7180b57cec5SDimitry Andric NewReg->addValue(RV);
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric }
7210b57cec5SDimitry Andric }
7220b57cec5SDimitry Andric };
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andric } // end anonymous namespace
7250b57cec5SDimitry Andric
7260b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7270b57cec5SDimitry Andric // CodeGenRegisterClass
7280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7290b57cec5SDimitry Andric
sortAndUniqueRegisters(CodeGenRegister::Vec & M)7300b57cec5SDimitry Andric static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) {
7318bcb0991SDimitry Andric llvm::sort(M, deref<std::less<>>());
7328bcb0991SDimitry Andric M.erase(std::unique(M.begin(), M.end(), deref<std::equal_to<>>()), M.end());
7330b57cec5SDimitry Andric }
7340b57cec5SDimitry Andric
CodeGenRegisterClass(CodeGenRegBank & RegBank,Record * R)7350b57cec5SDimitry Andric CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
7365ffd83dbSDimitry Andric : TheDef(R), Name(std::string(R->getName())),
7375ffd83dbSDimitry Andric TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1) {
7385ffd83dbSDimitry Andric GeneratePressureSet = R->getValueAsBit("GeneratePressureSet");
7390b57cec5SDimitry Andric std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
740af732203SDimitry Andric if (TypeList.empty())
741af732203SDimitry Andric PrintFatalError(R->getLoc(), "RegTypes list must not be empty!");
7420b57cec5SDimitry Andric for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
7430b57cec5SDimitry Andric Record *Type = TypeList[i];
7440b57cec5SDimitry Andric if (!Type->isSubClassOf("ValueType"))
7450b57cec5SDimitry Andric PrintFatalError(R->getLoc(),
7460b57cec5SDimitry Andric "RegTypes list member '" + Type->getName() +
7470b57cec5SDimitry Andric "' does not derive from the ValueType class!");
7480b57cec5SDimitry Andric VTs.push_back(getValueTypeByHwMode(Type, RegBank.getHwModes()));
7490b57cec5SDimitry Andric }
7500b57cec5SDimitry Andric
7510b57cec5SDimitry Andric // Allocation order 0 is the full set. AltOrders provides others.
7520b57cec5SDimitry Andric const SetTheory::RecVec *Elements = RegBank.getSets().expand(R);
7530b57cec5SDimitry Andric ListInit *AltOrders = R->getValueAsListInit("AltOrders");
7540b57cec5SDimitry Andric Orders.resize(1 + AltOrders->size());
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andric // Default allocation order always contains all registers.
7570b57cec5SDimitry Andric Artificial = true;
7580b57cec5SDimitry Andric for (unsigned i = 0, e = Elements->size(); i != e; ++i) {
7590b57cec5SDimitry Andric Orders[0].push_back((*Elements)[i]);
7600b57cec5SDimitry Andric const CodeGenRegister *Reg = RegBank.getReg((*Elements)[i]);
7610b57cec5SDimitry Andric Members.push_back(Reg);
7620b57cec5SDimitry Andric Artificial &= Reg->Artificial;
7630b57cec5SDimitry Andric TopoSigs.set(Reg->getTopoSig());
7640b57cec5SDimitry Andric }
7650b57cec5SDimitry Andric sortAndUniqueRegisters(Members);
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andric // Alternative allocation orders may be subsets.
7680b57cec5SDimitry Andric SetTheory::RecSet Order;
7690b57cec5SDimitry Andric for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) {
7700b57cec5SDimitry Andric RegBank.getSets().evaluate(AltOrders->getElement(i), Order, R->getLoc());
7710b57cec5SDimitry Andric Orders[1 + i].append(Order.begin(), Order.end());
7720b57cec5SDimitry Andric // Verify that all altorder members are regclass members.
7730b57cec5SDimitry Andric while (!Order.empty()) {
7740b57cec5SDimitry Andric CodeGenRegister *Reg = RegBank.getReg(Order.back());
7750b57cec5SDimitry Andric Order.pop_back();
7760b57cec5SDimitry Andric if (!contains(Reg))
7770b57cec5SDimitry Andric PrintFatalError(R->getLoc(), " AltOrder register " + Reg->getName() +
7780b57cec5SDimitry Andric " is not a class member");
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric }
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andric Namespace = R->getValueAsString("Namespace");
7830b57cec5SDimitry Andric
7840b57cec5SDimitry Andric if (const RecordVal *RV = R->getValue("RegInfos"))
7850b57cec5SDimitry Andric if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue()))
7860b57cec5SDimitry Andric RSI = RegSizeInfoByHwMode(DI->getDef(), RegBank.getHwModes());
7870b57cec5SDimitry Andric unsigned Size = R->getValueAsInt("Size");
7880b57cec5SDimitry Andric assert((RSI.hasDefault() || Size != 0 || VTs[0].isSimple()) &&
7890b57cec5SDimitry Andric "Impossible to determine register size");
7900b57cec5SDimitry Andric if (!RSI.hasDefault()) {
7910b57cec5SDimitry Andric RegSizeInfo RI;
7920b57cec5SDimitry Andric RI.RegSize = RI.SpillSize = Size ? Size
7930b57cec5SDimitry Andric : VTs[0].getSimple().getSizeInBits();
7940b57cec5SDimitry Andric RI.SpillAlignment = R->getValueAsInt("Alignment");
795*5f7ddb14SDimitry Andric RSI.insertRegSizeForMode(DefaultMode, RI);
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric CopyCost = R->getValueAsInt("CopyCost");
7990b57cec5SDimitry Andric Allocatable = R->getValueAsBit("isAllocatable");
8000b57cec5SDimitry Andric AltOrderSelect = R->getValueAsString("AltOrderSelect");
8010b57cec5SDimitry Andric int AllocationPriority = R->getValueAsInt("AllocationPriority");
8020b57cec5SDimitry Andric if (AllocationPriority < 0 || AllocationPriority > 63)
8030b57cec5SDimitry Andric PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,63]");
8040b57cec5SDimitry Andric this->AllocationPriority = AllocationPriority;
8050b57cec5SDimitry Andric }
8060b57cec5SDimitry Andric
8070b57cec5SDimitry Andric // Create an inferred register class that was missing from the .td files.
8080b57cec5SDimitry Andric // Most properties will be inherited from the closest super-class after the
8090b57cec5SDimitry Andric // class structure has been computed.
CodeGenRegisterClass(CodeGenRegBank & RegBank,StringRef Name,Key Props)8100b57cec5SDimitry Andric CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
8110b57cec5SDimitry Andric StringRef Name, Key Props)
8125ffd83dbSDimitry Andric : Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)),
8135ffd83dbSDimitry Andric TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI),
8145ffd83dbSDimitry Andric CopyCost(0), Allocatable(true), AllocationPriority(0) {
8150b57cec5SDimitry Andric Artificial = true;
8165ffd83dbSDimitry Andric GeneratePressureSet = false;
8170b57cec5SDimitry Andric for (const auto R : Members) {
8180b57cec5SDimitry Andric TopoSigs.set(R->getTopoSig());
8190b57cec5SDimitry Andric Artificial &= R->Artificial;
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric }
8220b57cec5SDimitry Andric
8230b57cec5SDimitry Andric // Compute inherited propertied for a synthesized register class.
inheritProperties(CodeGenRegBank & RegBank)8240b57cec5SDimitry Andric void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
8250b57cec5SDimitry Andric assert(!getDef() && "Only synthesized classes can inherit properties");
8260b57cec5SDimitry Andric assert(!SuperClasses.empty() && "Synthesized class without super class");
8270b57cec5SDimitry Andric
8280b57cec5SDimitry Andric // The last super-class is the smallest one.
8290b57cec5SDimitry Andric CodeGenRegisterClass &Super = *SuperClasses.back();
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric // Most properties are copied directly.
8320b57cec5SDimitry Andric // Exceptions are members, size, and alignment
8330b57cec5SDimitry Andric Namespace = Super.Namespace;
8340b57cec5SDimitry Andric VTs = Super.VTs;
8350b57cec5SDimitry Andric CopyCost = Super.CopyCost;
836*5f7ddb14SDimitry Andric // Check for allocatable superclasses.
837*5f7ddb14SDimitry Andric Allocatable = any_of(SuperClasses, [&](const CodeGenRegisterClass *S) {
838*5f7ddb14SDimitry Andric return S->Allocatable;
839*5f7ddb14SDimitry Andric });
8400b57cec5SDimitry Andric AltOrderSelect = Super.AltOrderSelect;
8410b57cec5SDimitry Andric AllocationPriority = Super.AllocationPriority;
8425ffd83dbSDimitry Andric GeneratePressureSet |= Super.GeneratePressureSet;
8430b57cec5SDimitry Andric
8440b57cec5SDimitry Andric // Copy all allocation orders, filter out foreign registers from the larger
8450b57cec5SDimitry Andric // super-class.
8460b57cec5SDimitry Andric Orders.resize(Super.Orders.size());
8470b57cec5SDimitry Andric for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i)
8480b57cec5SDimitry Andric for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j)
8490b57cec5SDimitry Andric if (contains(RegBank.getReg(Super.Orders[i][j])))
8500b57cec5SDimitry Andric Orders[i].push_back(Super.Orders[i][j]);
8510b57cec5SDimitry Andric }
8520b57cec5SDimitry Andric
contains(const CodeGenRegister * Reg) const8530b57cec5SDimitry Andric bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
8540b57cec5SDimitry Andric return std::binary_search(Members.begin(), Members.end(), Reg,
8558bcb0991SDimitry Andric deref<std::less<>>());
8560b57cec5SDimitry Andric }
8570b57cec5SDimitry Andric
getWeight(const CodeGenRegBank & RegBank) const8585ffd83dbSDimitry Andric unsigned CodeGenRegisterClass::getWeight(const CodeGenRegBank& RegBank) const {
8595ffd83dbSDimitry Andric if (TheDef && !TheDef->isValueUnset("Weight"))
8605ffd83dbSDimitry Andric return TheDef->getValueAsInt("Weight");
8615ffd83dbSDimitry Andric
8625ffd83dbSDimitry Andric if (Members.empty() || Artificial)
8635ffd83dbSDimitry Andric return 0;
8645ffd83dbSDimitry Andric
8655ffd83dbSDimitry Andric return (*Members.begin())->getWeight(RegBank);
8665ffd83dbSDimitry Andric }
8675ffd83dbSDimitry Andric
8680b57cec5SDimitry Andric namespace llvm {
8690b57cec5SDimitry Andric
operator <<(raw_ostream & OS,const CodeGenRegisterClass::Key & K)8700b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) {
8710b57cec5SDimitry Andric OS << "{ " << K.RSI;
8720b57cec5SDimitry Andric for (const auto R : *K.Members)
8730b57cec5SDimitry Andric OS << ", " << R->getName();
8740b57cec5SDimitry Andric return OS << " }";
8750b57cec5SDimitry Andric }
8760b57cec5SDimitry Andric
8770b57cec5SDimitry Andric } // end namespace llvm
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andric // This is a simple lexicographical order that can be used to search for sets.
8800b57cec5SDimitry Andric // It is not the same as the topological order provided by TopoOrderRC.
8810b57cec5SDimitry Andric bool CodeGenRegisterClass::Key::
operator <(const CodeGenRegisterClass::Key & B) const8820b57cec5SDimitry Andric operator<(const CodeGenRegisterClass::Key &B) const {
8830b57cec5SDimitry Andric assert(Members && B.Members);
8840b57cec5SDimitry Andric return std::tie(*Members, RSI) < std::tie(*B.Members, B.RSI);
8850b57cec5SDimitry Andric }
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric // Returns true if RC is a strict subclass.
8880b57cec5SDimitry Andric // RC is a sub-class of this class if it is a valid replacement for any
8890b57cec5SDimitry Andric // instruction operand where a register of this classis required. It must
8900b57cec5SDimitry Andric // satisfy these conditions:
8910b57cec5SDimitry Andric //
8920b57cec5SDimitry Andric // 1. All RC registers are also in this.
8930b57cec5SDimitry Andric // 2. The RC spill size must not be smaller than our spill size.
8940b57cec5SDimitry Andric // 3. RC spill alignment must be compatible with ours.
8950b57cec5SDimitry Andric //
testSubClass(const CodeGenRegisterClass * A,const CodeGenRegisterClass * B)8960b57cec5SDimitry Andric static bool testSubClass(const CodeGenRegisterClass *A,
8970b57cec5SDimitry Andric const CodeGenRegisterClass *B) {
8980b57cec5SDimitry Andric return A->RSI.isSubClassOf(B->RSI) &&
8990b57cec5SDimitry Andric std::includes(A->getMembers().begin(), A->getMembers().end(),
9000b57cec5SDimitry Andric B->getMembers().begin(), B->getMembers().end(),
9018bcb0991SDimitry Andric deref<std::less<>>());
9020b57cec5SDimitry Andric }
9030b57cec5SDimitry Andric
9040b57cec5SDimitry Andric /// Sorting predicate for register classes. This provides a topological
9050b57cec5SDimitry Andric /// ordering that arranges all register classes before their sub-classes.
9060b57cec5SDimitry Andric ///
9070b57cec5SDimitry Andric /// Register classes with the same registers, spill size, and alignment form a
9080b57cec5SDimitry Andric /// clique. They will be ordered alphabetically.
9090b57cec5SDimitry Andric ///
TopoOrderRC(const CodeGenRegisterClass & PA,const CodeGenRegisterClass & PB)9100b57cec5SDimitry Andric static bool TopoOrderRC(const CodeGenRegisterClass &PA,
9110b57cec5SDimitry Andric const CodeGenRegisterClass &PB) {
9120b57cec5SDimitry Andric auto *A = &PA;
9130b57cec5SDimitry Andric auto *B = &PB;
9140b57cec5SDimitry Andric if (A == B)
9150b57cec5SDimitry Andric return false;
9160b57cec5SDimitry Andric
9170b57cec5SDimitry Andric if (A->RSI < B->RSI)
9180b57cec5SDimitry Andric return true;
9190b57cec5SDimitry Andric if (A->RSI != B->RSI)
9200b57cec5SDimitry Andric return false;
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andric // Order by descending set size. Note that the classes' allocation order may
9230b57cec5SDimitry Andric // not have been computed yet. The Members set is always vaild.
9240b57cec5SDimitry Andric if (A->getMembers().size() > B->getMembers().size())
9250b57cec5SDimitry Andric return true;
9260b57cec5SDimitry Andric if (A->getMembers().size() < B->getMembers().size())
9270b57cec5SDimitry Andric return false;
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andric // Finally order by name as a tie breaker.
9300b57cec5SDimitry Andric return StringRef(A->getName()) < B->getName();
9310b57cec5SDimitry Andric }
9320b57cec5SDimitry Andric
getQualifiedName() const9330b57cec5SDimitry Andric std::string CodeGenRegisterClass::getQualifiedName() const {
9340b57cec5SDimitry Andric if (Namespace.empty())
9350b57cec5SDimitry Andric return getName();
9360b57cec5SDimitry Andric else
9370b57cec5SDimitry Andric return (Namespace + "::" + getName()).str();
9380b57cec5SDimitry Andric }
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andric // Compute sub-classes of all register classes.
9410b57cec5SDimitry Andric // Assume the classes are ordered topologically.
computeSubClasses(CodeGenRegBank & RegBank)9420b57cec5SDimitry Andric void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
9430b57cec5SDimitry Andric auto &RegClasses = RegBank.getRegClasses();
9440b57cec5SDimitry Andric
9450b57cec5SDimitry Andric // Visit backwards so sub-classes are seen first.
9460b57cec5SDimitry Andric for (auto I = RegClasses.rbegin(), E = RegClasses.rend(); I != E; ++I) {
9470b57cec5SDimitry Andric CodeGenRegisterClass &RC = *I;
9480b57cec5SDimitry Andric RC.SubClasses.resize(RegClasses.size());
9490b57cec5SDimitry Andric RC.SubClasses.set(RC.EnumValue);
9500b57cec5SDimitry Andric if (RC.Artificial)
9510b57cec5SDimitry Andric continue;
9520b57cec5SDimitry Andric
9530b57cec5SDimitry Andric // Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
9540b57cec5SDimitry Andric for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) {
9550b57cec5SDimitry Andric CodeGenRegisterClass &SubRC = *I2;
9560b57cec5SDimitry Andric if (RC.SubClasses.test(SubRC.EnumValue))
9570b57cec5SDimitry Andric continue;
9580b57cec5SDimitry Andric if (!testSubClass(&RC, &SubRC))
9590b57cec5SDimitry Andric continue;
9600b57cec5SDimitry Andric // SubRC is a sub-class. Grap all its sub-classes so we won't have to
9610b57cec5SDimitry Andric // check them again.
9620b57cec5SDimitry Andric RC.SubClasses |= SubRC.SubClasses;
9630b57cec5SDimitry Andric }
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andric // Sweep up missed clique members. They will be immediately preceding RC.
9660b57cec5SDimitry Andric for (auto I2 = std::next(I); I2 != E && testSubClass(&RC, &*I2); ++I2)
9670b57cec5SDimitry Andric RC.SubClasses.set(I2->EnumValue);
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric
9700b57cec5SDimitry Andric // Compute the SuperClasses lists from the SubClasses vectors.
9710b57cec5SDimitry Andric for (auto &RC : RegClasses) {
9720b57cec5SDimitry Andric const BitVector &SC = RC.getSubClasses();
9730b57cec5SDimitry Andric auto I = RegClasses.begin();
9740b57cec5SDimitry Andric for (int s = 0, next_s = SC.find_first(); next_s != -1;
9750b57cec5SDimitry Andric next_s = SC.find_next(s)) {
9760b57cec5SDimitry Andric std::advance(I, next_s - s);
9770b57cec5SDimitry Andric s = next_s;
9780b57cec5SDimitry Andric if (&*I == &RC)
9790b57cec5SDimitry Andric continue;
9800b57cec5SDimitry Andric I->SuperClasses.push_back(&RC);
9810b57cec5SDimitry Andric }
9820b57cec5SDimitry Andric }
9830b57cec5SDimitry Andric
9840b57cec5SDimitry Andric // With the class hierarchy in place, let synthesized register classes inherit
9850b57cec5SDimitry Andric // properties from their closest super-class. The iteration order here can
9860b57cec5SDimitry Andric // propagate properties down multiple levels.
9870b57cec5SDimitry Andric for (auto &RC : RegClasses)
9880b57cec5SDimitry Andric if (!RC.getDef())
9890b57cec5SDimitry Andric RC.inheritProperties(RegBank);
9900b57cec5SDimitry Andric }
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andric Optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
getMatchingSubClassWithSubRegs(CodeGenRegBank & RegBank,const CodeGenSubRegIndex * SubIdx) const9930b57cec5SDimitry Andric CodeGenRegisterClass::getMatchingSubClassWithSubRegs(
9940b57cec5SDimitry Andric CodeGenRegBank &RegBank, const CodeGenSubRegIndex *SubIdx) const {
9955ffd83dbSDimitry Andric auto SizeOrder = [this](const CodeGenRegisterClass *A,
9960b57cec5SDimitry Andric const CodeGenRegisterClass *B) {
9975ffd83dbSDimitry Andric // If there are multiple, identical register classes, prefer the original
9985ffd83dbSDimitry Andric // register class.
999af732203SDimitry Andric if (A == B)
1000af732203SDimitry Andric return false;
10015ffd83dbSDimitry Andric if (A->getMembers().size() == B->getMembers().size())
10025ffd83dbSDimitry Andric return A == this;
10030b57cec5SDimitry Andric return A->getMembers().size() > B->getMembers().size();
10040b57cec5SDimitry Andric };
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andric auto &RegClasses = RegBank.getRegClasses();
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andric // Find all the subclasses of this one that fully support the sub-register
10090b57cec5SDimitry Andric // index and order them by size. BiggestSuperRC should always be first.
10100b57cec5SDimitry Andric CodeGenRegisterClass *BiggestSuperRegRC = getSubClassWithSubReg(SubIdx);
10110b57cec5SDimitry Andric if (!BiggestSuperRegRC)
10120b57cec5SDimitry Andric return None;
10130b57cec5SDimitry Andric BitVector SuperRegRCsBV = BiggestSuperRegRC->getSubClasses();
10140b57cec5SDimitry Andric std::vector<CodeGenRegisterClass *> SuperRegRCs;
10150b57cec5SDimitry Andric for (auto &RC : RegClasses)
10160b57cec5SDimitry Andric if (SuperRegRCsBV[RC.EnumValue])
10170b57cec5SDimitry Andric SuperRegRCs.emplace_back(&RC);
10185ffd83dbSDimitry Andric llvm::stable_sort(SuperRegRCs, SizeOrder);
10195ffd83dbSDimitry Andric
10205ffd83dbSDimitry Andric assert(SuperRegRCs.front() == BiggestSuperRegRC &&
10215ffd83dbSDimitry Andric "Biggest class wasn't first");
10220b57cec5SDimitry Andric
10230b57cec5SDimitry Andric // Find all the subreg classes and order them by size too.
10240b57cec5SDimitry Andric std::vector<std::pair<CodeGenRegisterClass *, BitVector>> SuperRegClasses;
10250b57cec5SDimitry Andric for (auto &RC: RegClasses) {
10260b57cec5SDimitry Andric BitVector SuperRegClassesBV(RegClasses.size());
10270b57cec5SDimitry Andric RC.getSuperRegClasses(SubIdx, SuperRegClassesBV);
10280b57cec5SDimitry Andric if (SuperRegClassesBV.any())
10290b57cec5SDimitry Andric SuperRegClasses.push_back(std::make_pair(&RC, SuperRegClassesBV));
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric llvm::sort(SuperRegClasses,
10320b57cec5SDimitry Andric [&](const std::pair<CodeGenRegisterClass *, BitVector> &A,
10330b57cec5SDimitry Andric const std::pair<CodeGenRegisterClass *, BitVector> &B) {
10340b57cec5SDimitry Andric return SizeOrder(A.first, B.first);
10350b57cec5SDimitry Andric });
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andric // Find the biggest subclass and subreg class such that R:subidx is in the
10380b57cec5SDimitry Andric // subreg class for all R in subclass.
10390b57cec5SDimitry Andric //
10400b57cec5SDimitry Andric // For example:
10410b57cec5SDimitry Andric // All registers in X86's GR64 have a sub_32bit subregister but no class
10420b57cec5SDimitry Andric // exists that contains all the 32-bit subregisters because GR64 contains RIP
10430b57cec5SDimitry Andric // but GR32 does not contain EIP. Instead, we constrain SuperRegRC to
10440b57cec5SDimitry Andric // GR32_with_sub_8bit (which is identical to GR32_with_sub_32bit) and then,
10450b57cec5SDimitry Andric // having excluded RIP, we are able to find a SubRegRC (GR32).
10460b57cec5SDimitry Andric CodeGenRegisterClass *ChosenSuperRegClass = nullptr;
10470b57cec5SDimitry Andric CodeGenRegisterClass *SubRegRC = nullptr;
10480b57cec5SDimitry Andric for (auto *SuperRegRC : SuperRegRCs) {
10490b57cec5SDimitry Andric for (const auto &SuperRegClassPair : SuperRegClasses) {
10500b57cec5SDimitry Andric const BitVector &SuperRegClassBV = SuperRegClassPair.second;
10510b57cec5SDimitry Andric if (SuperRegClassBV[SuperRegRC->EnumValue]) {
10520b57cec5SDimitry Andric SubRegRC = SuperRegClassPair.first;
10530b57cec5SDimitry Andric ChosenSuperRegClass = SuperRegRC;
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric // If SubRegRC is bigger than SuperRegRC then there are members of
10560b57cec5SDimitry Andric // SubRegRC that don't have super registers via SubIdx. Keep looking to
10570b57cec5SDimitry Andric // find a better fit and fall back on this one if there isn't one.
10580b57cec5SDimitry Andric //
10590b57cec5SDimitry Andric // This is intended to prevent X86 from making odd choices such as
10600b57cec5SDimitry Andric // picking LOW32_ADDR_ACCESS_RBP instead of GR32 in the example above.
10610b57cec5SDimitry Andric // LOW32_ADDR_ACCESS_RBP is a valid choice but contains registers that
10620b57cec5SDimitry Andric // aren't subregisters of SuperRegRC whereas GR32 has a direct 1:1
10630b57cec5SDimitry Andric // mapping.
10640b57cec5SDimitry Andric if (SuperRegRC->getMembers().size() >= SubRegRC->getMembers().size())
10650b57cec5SDimitry Andric return std::make_pair(ChosenSuperRegClass, SubRegRC);
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric }
10680b57cec5SDimitry Andric
10690b57cec5SDimitry Andric // If we found a fit but it wasn't quite ideal because SubRegRC had excess
10700b57cec5SDimitry Andric // registers, then we're done.
10710b57cec5SDimitry Andric if (ChosenSuperRegClass)
10720b57cec5SDimitry Andric return std::make_pair(ChosenSuperRegClass, SubRegRC);
10730b57cec5SDimitry Andric }
10740b57cec5SDimitry Andric
10750b57cec5SDimitry Andric return None;
10760b57cec5SDimitry Andric }
10770b57cec5SDimitry Andric
getSuperRegClasses(const CodeGenSubRegIndex * SubIdx,BitVector & Out) const10780b57cec5SDimitry Andric void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
10790b57cec5SDimitry Andric BitVector &Out) const {
10800b57cec5SDimitry Andric auto FindI = SuperRegClasses.find(SubIdx);
10810b57cec5SDimitry Andric if (FindI == SuperRegClasses.end())
10820b57cec5SDimitry Andric return;
10830b57cec5SDimitry Andric for (CodeGenRegisterClass *RC : FindI->second)
10840b57cec5SDimitry Andric Out.set(RC->EnumValue);
10850b57cec5SDimitry Andric }
10860b57cec5SDimitry Andric
10870b57cec5SDimitry Andric // Populate a unique sorted list of units from a register set.
buildRegUnitSet(const CodeGenRegBank & RegBank,std::vector<unsigned> & RegUnits) const10880b57cec5SDimitry Andric void CodeGenRegisterClass::buildRegUnitSet(const CodeGenRegBank &RegBank,
10890b57cec5SDimitry Andric std::vector<unsigned> &RegUnits) const {
10900b57cec5SDimitry Andric std::vector<unsigned> TmpUnits;
10910b57cec5SDimitry Andric for (RegUnitIterator UnitI(Members); UnitI.isValid(); ++UnitI) {
10920b57cec5SDimitry Andric const RegUnit &RU = RegBank.getRegUnit(*UnitI);
10930b57cec5SDimitry Andric if (!RU.Artificial)
10940b57cec5SDimitry Andric TmpUnits.push_back(*UnitI);
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric llvm::sort(TmpUnits);
10970b57cec5SDimitry Andric std::unique_copy(TmpUnits.begin(), TmpUnits.end(),
10980b57cec5SDimitry Andric std::back_inserter(RegUnits));
10990b57cec5SDimitry Andric }
11000b57cec5SDimitry Andric
11010b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11020b57cec5SDimitry Andric // CodeGenRegBank
11030b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11040b57cec5SDimitry Andric
CodeGenRegBank(RecordKeeper & Records,const CodeGenHwModes & Modes)11050b57cec5SDimitry Andric CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records,
11060b57cec5SDimitry Andric const CodeGenHwModes &Modes) : CGH(Modes) {
11070b57cec5SDimitry Andric // Configure register Sets to understand register classes and tuples.
11080b57cec5SDimitry Andric Sets.addFieldExpander("RegisterClass", "MemberList");
11090b57cec5SDimitry Andric Sets.addFieldExpander("CalleeSavedRegs", "SaveList");
11100b57cec5SDimitry Andric Sets.addExpander("RegisterTuples",
11118bcb0991SDimitry Andric std::make_unique<TupleExpander>(SynthDefs));
11120b57cec5SDimitry Andric
11130b57cec5SDimitry Andric // Read in the user-defined (named) sub-register indices.
11140b57cec5SDimitry Andric // More indices will be synthesized later.
11150b57cec5SDimitry Andric std::vector<Record*> SRIs = Records.getAllDerivedDefinitions("SubRegIndex");
11160b57cec5SDimitry Andric llvm::sort(SRIs, LessRecord());
11170b57cec5SDimitry Andric for (unsigned i = 0, e = SRIs.size(); i != e; ++i)
11180b57cec5SDimitry Andric getSubRegIdx(SRIs[i]);
11190b57cec5SDimitry Andric // Build composite maps from ComposedOf fields.
11200b57cec5SDimitry Andric for (auto &Idx : SubRegIndices)
11210b57cec5SDimitry Andric Idx.updateComponents(*this);
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric // Read in the register definitions.
11240b57cec5SDimitry Andric std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
11250b57cec5SDimitry Andric llvm::sort(Regs, LessRecordRegister());
11260b57cec5SDimitry Andric // Assign the enumeration values.
11270b57cec5SDimitry Andric for (unsigned i = 0, e = Regs.size(); i != e; ++i)
11280b57cec5SDimitry Andric getReg(Regs[i]);
11290b57cec5SDimitry Andric
11300b57cec5SDimitry Andric // Expand tuples and number the new registers.
11310b57cec5SDimitry Andric std::vector<Record*> Tups =
11320b57cec5SDimitry Andric Records.getAllDerivedDefinitions("RegisterTuples");
11330b57cec5SDimitry Andric
11340b57cec5SDimitry Andric for (Record *R : Tups) {
11350b57cec5SDimitry Andric std::vector<Record *> TupRegs = *Sets.expand(R);
11360b57cec5SDimitry Andric llvm::sort(TupRegs, LessRecordRegister());
11370b57cec5SDimitry Andric for (Record *RC : TupRegs)
11380b57cec5SDimitry Andric getReg(RC);
11390b57cec5SDimitry Andric }
11400b57cec5SDimitry Andric
11410b57cec5SDimitry Andric // Now all the registers are known. Build the object graph of explicit
11420b57cec5SDimitry Andric // register-register references.
11430b57cec5SDimitry Andric for (auto &Reg : Registers)
11440b57cec5SDimitry Andric Reg.buildObjectGraph(*this);
11450b57cec5SDimitry Andric
11460b57cec5SDimitry Andric // Compute register name map.
11470b57cec5SDimitry Andric for (auto &Reg : Registers)
11480b57cec5SDimitry Andric // FIXME: This could just be RegistersByName[name] = register, except that
11490b57cec5SDimitry Andric // causes some failures in MIPS - perhaps they have duplicate register name
11500b57cec5SDimitry Andric // entries? (or maybe there's a reason for it - I don't know much about this
11510b57cec5SDimitry Andric // code, just drive-by refactoring)
11520b57cec5SDimitry Andric RegistersByName.insert(
11530b57cec5SDimitry Andric std::make_pair(Reg.TheDef->getValueAsString("AsmName"), &Reg));
11540b57cec5SDimitry Andric
11550b57cec5SDimitry Andric // Precompute all sub-register maps.
11560b57cec5SDimitry Andric // This will create Composite entries for all inferred sub-register indices.
11570b57cec5SDimitry Andric for (auto &Reg : Registers)
11580b57cec5SDimitry Andric Reg.computeSubRegs(*this);
11590b57cec5SDimitry Andric
11600b57cec5SDimitry Andric // Compute transitive closure of subregister index ConcatenationOf vectors
11610b57cec5SDimitry Andric // and initialize ConcatIdx map.
11620b57cec5SDimitry Andric for (CodeGenSubRegIndex &SRI : SubRegIndices) {
11630b57cec5SDimitry Andric SRI.computeConcatTransitiveClosure();
11640b57cec5SDimitry Andric if (!SRI.ConcatenationOf.empty())
11650b57cec5SDimitry Andric ConcatIdx.insert(std::make_pair(
11660b57cec5SDimitry Andric SmallVector<CodeGenSubRegIndex*,8>(SRI.ConcatenationOf.begin(),
11670b57cec5SDimitry Andric SRI.ConcatenationOf.end()), &SRI));
11680b57cec5SDimitry Andric }
11690b57cec5SDimitry Andric
11700b57cec5SDimitry Andric // Infer even more sub-registers by combining leading super-registers.
11710b57cec5SDimitry Andric for (auto &Reg : Registers)
11720b57cec5SDimitry Andric if (Reg.CoveredBySubRegs)
11730b57cec5SDimitry Andric Reg.computeSecondarySubRegs(*this);
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andric // After the sub-register graph is complete, compute the topologically
11760b57cec5SDimitry Andric // ordered SuperRegs list.
11770b57cec5SDimitry Andric for (auto &Reg : Registers)
11780b57cec5SDimitry Andric Reg.computeSuperRegs(*this);
11790b57cec5SDimitry Andric
11800b57cec5SDimitry Andric // For each pair of Reg:SR, if both are non-artificial, mark the
11810b57cec5SDimitry Andric // corresponding sub-register index as non-artificial.
11820b57cec5SDimitry Andric for (auto &Reg : Registers) {
11830b57cec5SDimitry Andric if (Reg.Artificial)
11840b57cec5SDimitry Andric continue;
11850b57cec5SDimitry Andric for (auto P : Reg.getSubRegs()) {
11860b57cec5SDimitry Andric const CodeGenRegister *SR = P.second;
11870b57cec5SDimitry Andric if (!SR->Artificial)
11880b57cec5SDimitry Andric P.first->Artificial = false;
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric }
11910b57cec5SDimitry Andric
11920b57cec5SDimitry Andric // Native register units are associated with a leaf register. They've all been
11930b57cec5SDimitry Andric // discovered now.
11940b57cec5SDimitry Andric NumNativeRegUnits = RegUnits.size();
11950b57cec5SDimitry Andric
11960b57cec5SDimitry Andric // Read in register class definitions.
11970b57cec5SDimitry Andric std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass");
11980b57cec5SDimitry Andric if (RCs.empty())
11990b57cec5SDimitry Andric PrintFatalError("No 'RegisterClass' subclasses defined!");
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andric // Allocate user-defined register classes.
12020b57cec5SDimitry Andric for (auto *R : RCs) {
12030b57cec5SDimitry Andric RegClasses.emplace_back(*this, R);
12040b57cec5SDimitry Andric CodeGenRegisterClass &RC = RegClasses.back();
12050b57cec5SDimitry Andric if (!RC.Artificial)
12060b57cec5SDimitry Andric addToMaps(&RC);
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric
12090b57cec5SDimitry Andric // Infer missing classes to create a full algebra.
12100b57cec5SDimitry Andric computeInferredRegisterClasses();
12110b57cec5SDimitry Andric
12120b57cec5SDimitry Andric // Order register classes topologically and assign enum values.
12130b57cec5SDimitry Andric RegClasses.sort(TopoOrderRC);
12140b57cec5SDimitry Andric unsigned i = 0;
12150b57cec5SDimitry Andric for (auto &RC : RegClasses)
12160b57cec5SDimitry Andric RC.EnumValue = i++;
12170b57cec5SDimitry Andric CodeGenRegisterClass::computeSubClasses(*this);
12180b57cec5SDimitry Andric }
12190b57cec5SDimitry Andric
12200b57cec5SDimitry Andric // Create a synthetic CodeGenSubRegIndex without a corresponding Record.
12210b57cec5SDimitry Andric CodeGenSubRegIndex*
createSubRegIndex(StringRef Name,StringRef Namespace)12220b57cec5SDimitry Andric CodeGenRegBank::createSubRegIndex(StringRef Name, StringRef Namespace) {
12230b57cec5SDimitry Andric SubRegIndices.emplace_back(Name, Namespace, SubRegIndices.size() + 1);
12240b57cec5SDimitry Andric return &SubRegIndices.back();
12250b57cec5SDimitry Andric }
12260b57cec5SDimitry Andric
getSubRegIdx(Record * Def)12270b57cec5SDimitry Andric CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) {
12280b57cec5SDimitry Andric CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def];
12290b57cec5SDimitry Andric if (Idx)
12300b57cec5SDimitry Andric return Idx;
12310b57cec5SDimitry Andric SubRegIndices.emplace_back(Def, SubRegIndices.size() + 1);
12320b57cec5SDimitry Andric Idx = &SubRegIndices.back();
12330b57cec5SDimitry Andric return Idx;
12340b57cec5SDimitry Andric }
12350b57cec5SDimitry Andric
12365ffd83dbSDimitry Andric const CodeGenSubRegIndex *
findSubRegIdx(const Record * Def) const12375ffd83dbSDimitry Andric CodeGenRegBank::findSubRegIdx(const Record* Def) const {
1238af732203SDimitry Andric return Def2SubRegIdx.lookup(Def);
12395ffd83dbSDimitry Andric }
12405ffd83dbSDimitry Andric
getReg(Record * Def)12410b57cec5SDimitry Andric CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
12420b57cec5SDimitry Andric CodeGenRegister *&Reg = Def2Reg[Def];
12430b57cec5SDimitry Andric if (Reg)
12440b57cec5SDimitry Andric return Reg;
12450b57cec5SDimitry Andric Registers.emplace_back(Def, Registers.size() + 1);
12460b57cec5SDimitry Andric Reg = &Registers.back();
12470b57cec5SDimitry Andric return Reg;
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric
addToMaps(CodeGenRegisterClass * RC)12500b57cec5SDimitry Andric void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) {
12510b57cec5SDimitry Andric if (Record *Def = RC->getDef())
12520b57cec5SDimitry Andric Def2RC.insert(std::make_pair(Def, RC));
12530b57cec5SDimitry Andric
12540b57cec5SDimitry Andric // Duplicate classes are rejected by insert().
12550b57cec5SDimitry Andric // That's OK, we only care about the properties handled by CGRC::Key.
12560b57cec5SDimitry Andric CodeGenRegisterClass::Key K(*RC);
12570b57cec5SDimitry Andric Key2RC.insert(std::make_pair(K, RC));
12580b57cec5SDimitry Andric }
12590b57cec5SDimitry Andric
12600b57cec5SDimitry Andric // Create a synthetic sub-class if it is missing.
12610b57cec5SDimitry Andric CodeGenRegisterClass*
getOrCreateSubClass(const CodeGenRegisterClass * RC,const CodeGenRegister::Vec * Members,StringRef Name)12620b57cec5SDimitry Andric CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
12630b57cec5SDimitry Andric const CodeGenRegister::Vec *Members,
12640b57cec5SDimitry Andric StringRef Name) {
12650b57cec5SDimitry Andric // Synthetic sub-class has the same size and alignment as RC.
12660b57cec5SDimitry Andric CodeGenRegisterClass::Key K(Members, RC->RSI);
12670b57cec5SDimitry Andric RCKeyMap::const_iterator FoundI = Key2RC.find(K);
12680b57cec5SDimitry Andric if (FoundI != Key2RC.end())
12690b57cec5SDimitry Andric return FoundI->second;
12700b57cec5SDimitry Andric
12710b57cec5SDimitry Andric // Sub-class doesn't exist, create a new one.
12720b57cec5SDimitry Andric RegClasses.emplace_back(*this, Name, K);
12730b57cec5SDimitry Andric addToMaps(&RegClasses.back());
12740b57cec5SDimitry Andric return &RegClasses.back();
12750b57cec5SDimitry Andric }
12760b57cec5SDimitry Andric
getRegClass(const Record * Def) const12775ffd83dbSDimitry Andric CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def) const {
12785ffd83dbSDimitry Andric if (CodeGenRegisterClass *RC = Def2RC.lookup(Def))
12790b57cec5SDimitry Andric return RC;
12800b57cec5SDimitry Andric
12810b57cec5SDimitry Andric PrintFatalError(Def->getLoc(), "Not a known RegisterClass!");
12820b57cec5SDimitry Andric }
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andric CodeGenSubRegIndex*
getCompositeSubRegIndex(CodeGenSubRegIndex * A,CodeGenSubRegIndex * B)12850b57cec5SDimitry Andric CodeGenRegBank::getCompositeSubRegIndex(CodeGenSubRegIndex *A,
12860b57cec5SDimitry Andric CodeGenSubRegIndex *B) {
12870b57cec5SDimitry Andric // Look for an existing entry.
12880b57cec5SDimitry Andric CodeGenSubRegIndex *Comp = A->compose(B);
12890b57cec5SDimitry Andric if (Comp)
12900b57cec5SDimitry Andric return Comp;
12910b57cec5SDimitry Andric
12920b57cec5SDimitry Andric // None exists, synthesize one.
12930b57cec5SDimitry Andric std::string Name = A->getName() + "_then_" + B->getName();
12940b57cec5SDimitry Andric Comp = createSubRegIndex(Name, A->getNamespace());
12950b57cec5SDimitry Andric A->addComposite(B, Comp);
12960b57cec5SDimitry Andric return Comp;
12970b57cec5SDimitry Andric }
12980b57cec5SDimitry Andric
12990b57cec5SDimitry Andric CodeGenSubRegIndex *CodeGenRegBank::
getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *,8> & Parts)13000b57cec5SDimitry Andric getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &Parts) {
13010b57cec5SDimitry Andric assert(Parts.size() > 1 && "Need two parts to concatenate");
13020b57cec5SDimitry Andric #ifndef NDEBUG
13030b57cec5SDimitry Andric for (CodeGenSubRegIndex *Idx : Parts) {
13040b57cec5SDimitry Andric assert(Idx->ConcatenationOf.empty() && "No transitive closure?");
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric #endif
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andric // Look for an existing entry.
13090b57cec5SDimitry Andric CodeGenSubRegIndex *&Idx = ConcatIdx[Parts];
13100b57cec5SDimitry Andric if (Idx)
13110b57cec5SDimitry Andric return Idx;
13120b57cec5SDimitry Andric
13130b57cec5SDimitry Andric // None exists, synthesize one.
13140b57cec5SDimitry Andric std::string Name = Parts.front()->getName();
13150b57cec5SDimitry Andric // Determine whether all parts are contiguous.
13160b57cec5SDimitry Andric bool isContinuous = true;
13170b57cec5SDimitry Andric unsigned Size = Parts.front()->Size;
13180b57cec5SDimitry Andric unsigned LastOffset = Parts.front()->Offset;
13190b57cec5SDimitry Andric unsigned LastSize = Parts.front()->Size;
13200b57cec5SDimitry Andric for (unsigned i = 1, e = Parts.size(); i != e; ++i) {
13210b57cec5SDimitry Andric Name += '_';
13220b57cec5SDimitry Andric Name += Parts[i]->getName();
13230b57cec5SDimitry Andric Size += Parts[i]->Size;
13240b57cec5SDimitry Andric if (Parts[i]->Offset != (LastOffset + LastSize))
13250b57cec5SDimitry Andric isContinuous = false;
13260b57cec5SDimitry Andric LastOffset = Parts[i]->Offset;
13270b57cec5SDimitry Andric LastSize = Parts[i]->Size;
13280b57cec5SDimitry Andric }
13290b57cec5SDimitry Andric Idx = createSubRegIndex(Name, Parts.front()->getNamespace());
13300b57cec5SDimitry Andric Idx->Size = Size;
13310b57cec5SDimitry Andric Idx->Offset = isContinuous ? Parts.front()->Offset : -1;
13320b57cec5SDimitry Andric Idx->ConcatenationOf.assign(Parts.begin(), Parts.end());
13330b57cec5SDimitry Andric return Idx;
13340b57cec5SDimitry Andric }
13350b57cec5SDimitry Andric
computeComposites()13360b57cec5SDimitry Andric void CodeGenRegBank::computeComposites() {
13370b57cec5SDimitry Andric using RegMap = std::map<const CodeGenRegister*, const CodeGenRegister*>;
13380b57cec5SDimitry Andric
13390b57cec5SDimitry Andric // Subreg -> { Reg->Reg }, where the right-hand side is the mapping from
13400b57cec5SDimitry Andric // register to (sub)register associated with the action of the left-hand
13410b57cec5SDimitry Andric // side subregister.
13420b57cec5SDimitry Andric std::map<const CodeGenSubRegIndex*, RegMap> SubRegAction;
13430b57cec5SDimitry Andric for (const CodeGenRegister &R : Registers) {
13440b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &SM = R.getSubRegs();
13450b57cec5SDimitry Andric for (std::pair<const CodeGenSubRegIndex*, const CodeGenRegister*> P : SM)
13460b57cec5SDimitry Andric SubRegAction[P.first].insert({&R, P.second});
13470b57cec5SDimitry Andric }
13480b57cec5SDimitry Andric
13490b57cec5SDimitry Andric // Calculate the composition of two subregisters as compositions of their
13500b57cec5SDimitry Andric // associated actions.
13510b57cec5SDimitry Andric auto compose = [&SubRegAction] (const CodeGenSubRegIndex *Sub1,
13520b57cec5SDimitry Andric const CodeGenSubRegIndex *Sub2) {
13530b57cec5SDimitry Andric RegMap C;
13540b57cec5SDimitry Andric const RegMap &Img1 = SubRegAction.at(Sub1);
13550b57cec5SDimitry Andric const RegMap &Img2 = SubRegAction.at(Sub2);
13560b57cec5SDimitry Andric for (std::pair<const CodeGenRegister*, const CodeGenRegister*> P : Img1) {
13570b57cec5SDimitry Andric auto F = Img2.find(P.second);
13580b57cec5SDimitry Andric if (F != Img2.end())
13590b57cec5SDimitry Andric C.insert({P.first, F->second});
13600b57cec5SDimitry Andric }
13610b57cec5SDimitry Andric return C;
13620b57cec5SDimitry Andric };
13630b57cec5SDimitry Andric
13640b57cec5SDimitry Andric // Check if the two maps agree on the intersection of their domains.
13650b57cec5SDimitry Andric auto agree = [] (const RegMap &Map1, const RegMap &Map2) {
13660b57cec5SDimitry Andric // Technically speaking, an empty map agrees with any other map, but
13670b57cec5SDimitry Andric // this could flag false positives. We're interested in non-vacuous
13680b57cec5SDimitry Andric // agreements.
13690b57cec5SDimitry Andric if (Map1.empty() || Map2.empty())
13700b57cec5SDimitry Andric return false;
13710b57cec5SDimitry Andric for (std::pair<const CodeGenRegister*, const CodeGenRegister*> P : Map1) {
13720b57cec5SDimitry Andric auto F = Map2.find(P.first);
13730b57cec5SDimitry Andric if (F == Map2.end() || P.second != F->second)
13740b57cec5SDimitry Andric return false;
13750b57cec5SDimitry Andric }
13760b57cec5SDimitry Andric return true;
13770b57cec5SDimitry Andric };
13780b57cec5SDimitry Andric
13790b57cec5SDimitry Andric using CompositePair = std::pair<const CodeGenSubRegIndex*,
13800b57cec5SDimitry Andric const CodeGenSubRegIndex*>;
13810b57cec5SDimitry Andric SmallSet<CompositePair,4> UserDefined;
13820b57cec5SDimitry Andric for (const CodeGenSubRegIndex &Idx : SubRegIndices)
13830b57cec5SDimitry Andric for (auto P : Idx.getComposites())
13840b57cec5SDimitry Andric UserDefined.insert(std::make_pair(&Idx, P.first));
13850b57cec5SDimitry Andric
13860b57cec5SDimitry Andric // Keep track of TopoSigs visited. We only need to visit each TopoSig once,
13870b57cec5SDimitry Andric // and many registers will share TopoSigs on regular architectures.
13880b57cec5SDimitry Andric BitVector TopoSigs(getNumTopoSigs());
13890b57cec5SDimitry Andric
13900b57cec5SDimitry Andric for (const auto &Reg1 : Registers) {
13910b57cec5SDimitry Andric // Skip identical subreg structures already processed.
13920b57cec5SDimitry Andric if (TopoSigs.test(Reg1.getTopoSig()))
13930b57cec5SDimitry Andric continue;
13940b57cec5SDimitry Andric TopoSigs.set(Reg1.getTopoSig());
13950b57cec5SDimitry Andric
13960b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &SRM1 = Reg1.getSubRegs();
1397*5f7ddb14SDimitry Andric for (auto I1 : SRM1) {
1398*5f7ddb14SDimitry Andric CodeGenSubRegIndex *Idx1 = I1.first;
1399*5f7ddb14SDimitry Andric CodeGenRegister *Reg2 = I1.second;
14000b57cec5SDimitry Andric // Ignore identity compositions.
14010b57cec5SDimitry Andric if (&Reg1 == Reg2)
14020b57cec5SDimitry Andric continue;
14030b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs();
14040b57cec5SDimitry Andric // Try composing Idx1 with another SubRegIndex.
1405*5f7ddb14SDimitry Andric for (auto I2 : SRM2) {
1406*5f7ddb14SDimitry Andric CodeGenSubRegIndex *Idx2 = I2.first;
1407*5f7ddb14SDimitry Andric CodeGenRegister *Reg3 = I2.second;
14080b57cec5SDimitry Andric // Ignore identity compositions.
14090b57cec5SDimitry Andric if (Reg2 == Reg3)
14100b57cec5SDimitry Andric continue;
14110b57cec5SDimitry Andric // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3.
14120b57cec5SDimitry Andric CodeGenSubRegIndex *Idx3 = Reg1.getSubRegIndex(Reg3);
14130b57cec5SDimitry Andric assert(Idx3 && "Sub-register doesn't have an index");
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andric // Conflicting composition? Emit a warning but allow it.
14160b57cec5SDimitry Andric if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, Idx3)) {
14170b57cec5SDimitry Andric // If the composition was not user-defined, always emit a warning.
14180b57cec5SDimitry Andric if (!UserDefined.count({Idx1, Idx2}) ||
14190b57cec5SDimitry Andric agree(compose(Idx1, Idx2), SubRegAction.at(Idx3)))
14200b57cec5SDimitry Andric PrintWarning(Twine("SubRegIndex ") + Idx1->getQualifiedName() +
14210b57cec5SDimitry Andric " and " + Idx2->getQualifiedName() +
14220b57cec5SDimitry Andric " compose ambiguously as " + Prev->getQualifiedName() +
14230b57cec5SDimitry Andric " or " + Idx3->getQualifiedName());
14240b57cec5SDimitry Andric }
14250b57cec5SDimitry Andric }
14260b57cec5SDimitry Andric }
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric }
14290b57cec5SDimitry Andric
14300b57cec5SDimitry Andric // Compute lane masks. This is similar to register units, but at the
14310b57cec5SDimitry Andric // sub-register index level. Each bit in the lane mask is like a register unit
14320b57cec5SDimitry Andric // class, and two lane masks will have a bit in common if two sub-register
14330b57cec5SDimitry Andric // indices overlap in some register.
14340b57cec5SDimitry Andric //
14350b57cec5SDimitry Andric // Conservatively share a lane mask bit if two sub-register indices overlap in
14360b57cec5SDimitry Andric // some registers, but not in others. That shouldn't happen a lot.
computeSubRegLaneMasks()14370b57cec5SDimitry Andric void CodeGenRegBank::computeSubRegLaneMasks() {
14380b57cec5SDimitry Andric // First assign individual bits to all the leaf indices.
14390b57cec5SDimitry Andric unsigned Bit = 0;
14400b57cec5SDimitry Andric // Determine mask of lanes that cover their registers.
14410b57cec5SDimitry Andric CoveringLanes = LaneBitmask::getAll();
14420b57cec5SDimitry Andric for (auto &Idx : SubRegIndices) {
14430b57cec5SDimitry Andric if (Idx.getComposites().empty()) {
14440b57cec5SDimitry Andric if (Bit > LaneBitmask::BitWidth) {
14450b57cec5SDimitry Andric PrintFatalError(
14460b57cec5SDimitry Andric Twine("Ran out of lanemask bits to represent subregister ")
14470b57cec5SDimitry Andric + Idx.getName());
14480b57cec5SDimitry Andric }
14490b57cec5SDimitry Andric Idx.LaneMask = LaneBitmask::getLane(Bit);
14500b57cec5SDimitry Andric ++Bit;
14510b57cec5SDimitry Andric } else {
14520b57cec5SDimitry Andric Idx.LaneMask = LaneBitmask::getNone();
14530b57cec5SDimitry Andric }
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric
14560b57cec5SDimitry Andric // Compute transformation sequences for composeSubRegIndexLaneMask. The idea
14570b57cec5SDimitry Andric // here is that for each possible target subregister we look at the leafs
14580b57cec5SDimitry Andric // in the subregister graph that compose for this target and create
14590b57cec5SDimitry Andric // transformation sequences for the lanemasks. Each step in the sequence
14600b57cec5SDimitry Andric // consists of a bitmask and a bitrotate operation. As the rotation amounts
14610b57cec5SDimitry Andric // are usually the same for many subregisters we can easily combine the steps
14620b57cec5SDimitry Andric // by combining the masks.
14630b57cec5SDimitry Andric for (const auto &Idx : SubRegIndices) {
14640b57cec5SDimitry Andric const auto &Composites = Idx.getComposites();
14650b57cec5SDimitry Andric auto &LaneTransforms = Idx.CompositionLaneMaskTransform;
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric if (Composites.empty()) {
14680b57cec5SDimitry Andric // Moving from a class with no subregisters we just had a single lane:
14690b57cec5SDimitry Andric // The subregister must be a leaf subregister and only occupies 1 bit.
14700b57cec5SDimitry Andric // Move the bit from the class without subregisters into that position.
14710b57cec5SDimitry Andric unsigned DstBit = Idx.LaneMask.getHighestLane();
14720b57cec5SDimitry Andric assert(Idx.LaneMask == LaneBitmask::getLane(DstBit) &&
14730b57cec5SDimitry Andric "Must be a leaf subregister");
14740b57cec5SDimitry Andric MaskRolPair MaskRol = { LaneBitmask::getLane(0), (uint8_t)DstBit };
14750b57cec5SDimitry Andric LaneTransforms.push_back(MaskRol);
14760b57cec5SDimitry Andric } else {
14770b57cec5SDimitry Andric // Go through all leaf subregisters and find the ones that compose with
14780b57cec5SDimitry Andric // Idx. These make out all possible valid bits in the lane mask we want to
14790b57cec5SDimitry Andric // transform. Looking only at the leafs ensure that only a single bit in
14800b57cec5SDimitry Andric // the mask is set.
14810b57cec5SDimitry Andric unsigned NextBit = 0;
14820b57cec5SDimitry Andric for (auto &Idx2 : SubRegIndices) {
14830b57cec5SDimitry Andric // Skip non-leaf subregisters.
14840b57cec5SDimitry Andric if (!Idx2.getComposites().empty())
14850b57cec5SDimitry Andric continue;
14860b57cec5SDimitry Andric // Replicate the behaviour from the lane mask generation loop above.
14870b57cec5SDimitry Andric unsigned SrcBit = NextBit;
14880b57cec5SDimitry Andric LaneBitmask SrcMask = LaneBitmask::getLane(SrcBit);
14890b57cec5SDimitry Andric if (NextBit < LaneBitmask::BitWidth-1)
14900b57cec5SDimitry Andric ++NextBit;
14910b57cec5SDimitry Andric assert(Idx2.LaneMask == SrcMask);
14920b57cec5SDimitry Andric
14930b57cec5SDimitry Andric // Get the composed subregister if there is any.
14940b57cec5SDimitry Andric auto C = Composites.find(&Idx2);
14950b57cec5SDimitry Andric if (C == Composites.end())
14960b57cec5SDimitry Andric continue;
14970b57cec5SDimitry Andric const CodeGenSubRegIndex *Composite = C->second;
14980b57cec5SDimitry Andric // The Composed subreg should be a leaf subreg too
14990b57cec5SDimitry Andric assert(Composite->getComposites().empty());
15000b57cec5SDimitry Andric
15010b57cec5SDimitry Andric // Create Mask+Rotate operation and merge with existing ops if possible.
15020b57cec5SDimitry Andric unsigned DstBit = Composite->LaneMask.getHighestLane();
15030b57cec5SDimitry Andric int Shift = DstBit - SrcBit;
15040b57cec5SDimitry Andric uint8_t RotateLeft = Shift >= 0 ? (uint8_t)Shift
15050b57cec5SDimitry Andric : LaneBitmask::BitWidth + Shift;
15060b57cec5SDimitry Andric for (auto &I : LaneTransforms) {
15070b57cec5SDimitry Andric if (I.RotateLeft == RotateLeft) {
15080b57cec5SDimitry Andric I.Mask |= SrcMask;
15090b57cec5SDimitry Andric SrcMask = LaneBitmask::getNone();
15100b57cec5SDimitry Andric }
15110b57cec5SDimitry Andric }
15120b57cec5SDimitry Andric if (SrcMask.any()) {
15130b57cec5SDimitry Andric MaskRolPair MaskRol = { SrcMask, RotateLeft };
15140b57cec5SDimitry Andric LaneTransforms.push_back(MaskRol);
15150b57cec5SDimitry Andric }
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric }
15180b57cec5SDimitry Andric
15190b57cec5SDimitry Andric // Optimize if the transformation consists of one step only: Set mask to
15200b57cec5SDimitry Andric // 0xffffffff (including some irrelevant invalid bits) so that it should
15210b57cec5SDimitry Andric // merge with more entries later while compressing the table.
15220b57cec5SDimitry Andric if (LaneTransforms.size() == 1)
15230b57cec5SDimitry Andric LaneTransforms[0].Mask = LaneBitmask::getAll();
15240b57cec5SDimitry Andric
15250b57cec5SDimitry Andric // Further compression optimization: For invalid compositions resulting
15260b57cec5SDimitry Andric // in a sequence with 0 entries we can just pick any other. Choose
15270b57cec5SDimitry Andric // Mask 0xffffffff with Rotation 0.
15280b57cec5SDimitry Andric if (LaneTransforms.size() == 0) {
15290b57cec5SDimitry Andric MaskRolPair P = { LaneBitmask::getAll(), 0 };
15300b57cec5SDimitry Andric LaneTransforms.push_back(P);
15310b57cec5SDimitry Andric }
15320b57cec5SDimitry Andric }
15330b57cec5SDimitry Andric
15340b57cec5SDimitry Andric // FIXME: What if ad-hoc aliasing introduces overlaps that aren't represented
15350b57cec5SDimitry Andric // by the sub-register graph? This doesn't occur in any known targets.
15360b57cec5SDimitry Andric
15370b57cec5SDimitry Andric // Inherit lanes from composites.
15380b57cec5SDimitry Andric for (const auto &Idx : SubRegIndices) {
15390b57cec5SDimitry Andric LaneBitmask Mask = Idx.computeLaneMask();
15400b57cec5SDimitry Andric // If some super-registers without CoveredBySubRegs use this index, we can
15410b57cec5SDimitry Andric // no longer assume that the lanes are covering their registers.
15420b57cec5SDimitry Andric if (!Idx.AllSuperRegsCovered)
15430b57cec5SDimitry Andric CoveringLanes &= ~Mask;
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric
15460b57cec5SDimitry Andric // Compute lane mask combinations for register classes.
15470b57cec5SDimitry Andric for (auto &RegClass : RegClasses) {
15480b57cec5SDimitry Andric LaneBitmask LaneMask;
15490b57cec5SDimitry Andric for (const auto &SubRegIndex : SubRegIndices) {
15500b57cec5SDimitry Andric if (RegClass.getSubClassWithSubReg(&SubRegIndex) == nullptr)
15510b57cec5SDimitry Andric continue;
15520b57cec5SDimitry Andric LaneMask |= SubRegIndex.LaneMask;
15530b57cec5SDimitry Andric }
15540b57cec5SDimitry Andric
15550b57cec5SDimitry Andric // For classes without any subregisters set LaneMask to 1 instead of 0.
15560b57cec5SDimitry Andric // This makes it easier for client code to handle classes uniformly.
15570b57cec5SDimitry Andric if (LaneMask.none())
15580b57cec5SDimitry Andric LaneMask = LaneBitmask::getLane(0);
15590b57cec5SDimitry Andric
15600b57cec5SDimitry Andric RegClass.LaneMask = LaneMask;
15610b57cec5SDimitry Andric }
15620b57cec5SDimitry Andric }
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andric namespace {
15650b57cec5SDimitry Andric
15660b57cec5SDimitry Andric // UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is
15670b57cec5SDimitry Andric // the transitive closure of the union of overlapping register
15680b57cec5SDimitry Andric // classes. Together, the UberRegSets form a partition of the registers. If we
15690b57cec5SDimitry Andric // consider overlapping register classes to be connected, then each UberRegSet
15700b57cec5SDimitry Andric // is a set of connected components.
15710b57cec5SDimitry Andric //
15720b57cec5SDimitry Andric // An UberRegSet will likely be a horizontal slice of register names of
15730b57cec5SDimitry Andric // the same width. Nontrivial subregisters should then be in a separate
15740b57cec5SDimitry Andric // UberRegSet. But this property isn't required for valid computation of
15750b57cec5SDimitry Andric // register unit weights.
15760b57cec5SDimitry Andric //
15770b57cec5SDimitry Andric // A Weight field caches the max per-register unit weight in each UberRegSet.
15780b57cec5SDimitry Andric //
15790b57cec5SDimitry Andric // A set of SingularDeterminants flags single units of some register in this set
15800b57cec5SDimitry Andric // for which the unit weight equals the set weight. These units should not have
15810b57cec5SDimitry Andric // their weight increased.
15820b57cec5SDimitry Andric struct UberRegSet {
15830b57cec5SDimitry Andric CodeGenRegister::Vec Regs;
15840b57cec5SDimitry Andric unsigned Weight = 0;
15850b57cec5SDimitry Andric CodeGenRegister::RegUnitList SingularDeterminants;
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andric UberRegSet() = default;
15880b57cec5SDimitry Andric };
15890b57cec5SDimitry Andric
15900b57cec5SDimitry Andric } // end anonymous namespace
15910b57cec5SDimitry Andric
15920b57cec5SDimitry Andric // Partition registers into UberRegSets, where each set is the transitive
15930b57cec5SDimitry Andric // closure of the union of overlapping register classes.
15940b57cec5SDimitry Andric //
15950b57cec5SDimitry Andric // UberRegSets[0] is a special non-allocatable set.
computeUberSets(std::vector<UberRegSet> & UberSets,std::vector<UberRegSet * > & RegSets,CodeGenRegBank & RegBank)15960b57cec5SDimitry Andric static void computeUberSets(std::vector<UberRegSet> &UberSets,
15970b57cec5SDimitry Andric std::vector<UberRegSet*> &RegSets,
15980b57cec5SDimitry Andric CodeGenRegBank &RegBank) {
15990b57cec5SDimitry Andric const auto &Registers = RegBank.getRegisters();
16000b57cec5SDimitry Andric
16010b57cec5SDimitry Andric // The Register EnumValue is one greater than its index into Registers.
16020b57cec5SDimitry Andric assert(Registers.size() == Registers.back().EnumValue &&
16030b57cec5SDimitry Andric "register enum value mismatch");
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andric // For simplicitly make the SetID the same as EnumValue.
16060b57cec5SDimitry Andric IntEqClasses UberSetIDs(Registers.size()+1);
16070b57cec5SDimitry Andric std::set<unsigned> AllocatableRegs;
16080b57cec5SDimitry Andric for (auto &RegClass : RegBank.getRegClasses()) {
16090b57cec5SDimitry Andric if (!RegClass.Allocatable)
16100b57cec5SDimitry Andric continue;
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andric const CodeGenRegister::Vec &Regs = RegClass.getMembers();
16130b57cec5SDimitry Andric if (Regs.empty())
16140b57cec5SDimitry Andric continue;
16150b57cec5SDimitry Andric
16160b57cec5SDimitry Andric unsigned USetID = UberSetIDs.findLeader((*Regs.begin())->EnumValue);
16170b57cec5SDimitry Andric assert(USetID && "register number 0 is invalid");
16180b57cec5SDimitry Andric
16190b57cec5SDimitry Andric AllocatableRegs.insert((*Regs.begin())->EnumValue);
16200b57cec5SDimitry Andric for (auto I = std::next(Regs.begin()), E = Regs.end(); I != E; ++I) {
16210b57cec5SDimitry Andric AllocatableRegs.insert((*I)->EnumValue);
16220b57cec5SDimitry Andric UberSetIDs.join(USetID, (*I)->EnumValue);
16230b57cec5SDimitry Andric }
16240b57cec5SDimitry Andric }
16250b57cec5SDimitry Andric // Combine non-allocatable regs.
16260b57cec5SDimitry Andric for (const auto &Reg : Registers) {
16270b57cec5SDimitry Andric unsigned RegNum = Reg.EnumValue;
16280b57cec5SDimitry Andric if (AllocatableRegs.count(RegNum))
16290b57cec5SDimitry Andric continue;
16300b57cec5SDimitry Andric
16310b57cec5SDimitry Andric UberSetIDs.join(0, RegNum);
16320b57cec5SDimitry Andric }
16330b57cec5SDimitry Andric UberSetIDs.compress();
16340b57cec5SDimitry Andric
16350b57cec5SDimitry Andric // Make the first UberSet a special unallocatable set.
16360b57cec5SDimitry Andric unsigned ZeroID = UberSetIDs[0];
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andric // Insert Registers into the UberSets formed by union-find.
16390b57cec5SDimitry Andric // Do not resize after this.
16400b57cec5SDimitry Andric UberSets.resize(UberSetIDs.getNumClasses());
16410b57cec5SDimitry Andric unsigned i = 0;
16420b57cec5SDimitry Andric for (const CodeGenRegister &Reg : Registers) {
16430b57cec5SDimitry Andric unsigned USetID = UberSetIDs[Reg.EnumValue];
16440b57cec5SDimitry Andric if (!USetID)
16450b57cec5SDimitry Andric USetID = ZeroID;
16460b57cec5SDimitry Andric else if (USetID == ZeroID)
16470b57cec5SDimitry Andric USetID = 0;
16480b57cec5SDimitry Andric
16490b57cec5SDimitry Andric UberRegSet *USet = &UberSets[USetID];
16500b57cec5SDimitry Andric USet->Regs.push_back(&Reg);
16510b57cec5SDimitry Andric sortAndUniqueRegisters(USet->Regs);
16520b57cec5SDimitry Andric RegSets[i++] = USet;
16530b57cec5SDimitry Andric }
16540b57cec5SDimitry Andric }
16550b57cec5SDimitry Andric
16560b57cec5SDimitry Andric // Recompute each UberSet weight after changing unit weights.
computeUberWeights(std::vector<UberRegSet> & UberSets,CodeGenRegBank & RegBank)16570b57cec5SDimitry Andric static void computeUberWeights(std::vector<UberRegSet> &UberSets,
16580b57cec5SDimitry Andric CodeGenRegBank &RegBank) {
16590b57cec5SDimitry Andric // Skip the first unallocatable set.
16600b57cec5SDimitry Andric for (std::vector<UberRegSet>::iterator I = std::next(UberSets.begin()),
16610b57cec5SDimitry Andric E = UberSets.end(); I != E; ++I) {
16620b57cec5SDimitry Andric
16630b57cec5SDimitry Andric // Initialize all unit weights in this set, and remember the max units/reg.
16640b57cec5SDimitry Andric const CodeGenRegister *Reg = nullptr;
16650b57cec5SDimitry Andric unsigned MaxWeight = 0, Weight = 0;
16660b57cec5SDimitry Andric for (RegUnitIterator UnitI(I->Regs); UnitI.isValid(); ++UnitI) {
16670b57cec5SDimitry Andric if (Reg != UnitI.getReg()) {
16680b57cec5SDimitry Andric if (Weight > MaxWeight)
16690b57cec5SDimitry Andric MaxWeight = Weight;
16700b57cec5SDimitry Andric Reg = UnitI.getReg();
16710b57cec5SDimitry Andric Weight = 0;
16720b57cec5SDimitry Andric }
16730b57cec5SDimitry Andric if (!RegBank.getRegUnit(*UnitI).Artificial) {
16740b57cec5SDimitry Andric unsigned UWeight = RegBank.getRegUnit(*UnitI).Weight;
16750b57cec5SDimitry Andric if (!UWeight) {
16760b57cec5SDimitry Andric UWeight = 1;
16770b57cec5SDimitry Andric RegBank.increaseRegUnitWeight(*UnitI, UWeight);
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric Weight += UWeight;
16800b57cec5SDimitry Andric }
16810b57cec5SDimitry Andric }
16820b57cec5SDimitry Andric if (Weight > MaxWeight)
16830b57cec5SDimitry Andric MaxWeight = Weight;
16840b57cec5SDimitry Andric if (I->Weight != MaxWeight) {
16850b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "UberSet " << I - UberSets.begin() << " Weight "
16860b57cec5SDimitry Andric << MaxWeight;
16870b57cec5SDimitry Andric for (auto &Unit
16880b57cec5SDimitry Andric : I->Regs) dbgs()
16890b57cec5SDimitry Andric << " " << Unit->getName();
16900b57cec5SDimitry Andric dbgs() << "\n");
16910b57cec5SDimitry Andric // Update the set weight.
16920b57cec5SDimitry Andric I->Weight = MaxWeight;
16930b57cec5SDimitry Andric }
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andric // Find singular determinants.
16960b57cec5SDimitry Andric for (const auto R : I->Regs) {
16970b57cec5SDimitry Andric if (R->getRegUnits().count() == 1 && R->getWeight(RegBank) == I->Weight) {
16980b57cec5SDimitry Andric I->SingularDeterminants |= R->getRegUnits();
16990b57cec5SDimitry Andric }
17000b57cec5SDimitry Andric }
17010b57cec5SDimitry Andric }
17020b57cec5SDimitry Andric }
17030b57cec5SDimitry Andric
17040b57cec5SDimitry Andric // normalizeWeight is a computeRegUnitWeights helper that adjusts the weight of
17050b57cec5SDimitry Andric // a register and its subregisters so that they have the same weight as their
17060b57cec5SDimitry Andric // UberSet. Self-recursion processes the subregister tree in postorder so
17070b57cec5SDimitry Andric // subregisters are normalized first.
17080b57cec5SDimitry Andric //
17090b57cec5SDimitry Andric // Side effects:
17100b57cec5SDimitry Andric // - creates new adopted register units
17110b57cec5SDimitry Andric // - causes superregisters to inherit adopted units
17120b57cec5SDimitry Andric // - increases the weight of "singular" units
17130b57cec5SDimitry Andric // - induces recomputation of UberWeights.
normalizeWeight(CodeGenRegister * Reg,std::vector<UberRegSet> & UberSets,std::vector<UberRegSet * > & RegSets,BitVector & NormalRegs,CodeGenRegister::RegUnitList & NormalUnits,CodeGenRegBank & RegBank)17140b57cec5SDimitry Andric static bool normalizeWeight(CodeGenRegister *Reg,
17150b57cec5SDimitry Andric std::vector<UberRegSet> &UberSets,
17160b57cec5SDimitry Andric std::vector<UberRegSet*> &RegSets,
17170b57cec5SDimitry Andric BitVector &NormalRegs,
17180b57cec5SDimitry Andric CodeGenRegister::RegUnitList &NormalUnits,
17190b57cec5SDimitry Andric CodeGenRegBank &RegBank) {
17200b57cec5SDimitry Andric NormalRegs.resize(std::max(Reg->EnumValue + 1, NormalRegs.size()));
17210b57cec5SDimitry Andric if (NormalRegs.test(Reg->EnumValue))
17220b57cec5SDimitry Andric return false;
17230b57cec5SDimitry Andric NormalRegs.set(Reg->EnumValue);
17240b57cec5SDimitry Andric
17250b57cec5SDimitry Andric bool Changed = false;
17260b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs();
1727*5f7ddb14SDimitry Andric for (auto SRI : SRM) {
1728*5f7ddb14SDimitry Andric if (SRI.second == Reg)
17290b57cec5SDimitry Andric continue; // self-cycles happen
17300b57cec5SDimitry Andric
1731*5f7ddb14SDimitry Andric Changed |= normalizeWeight(SRI.second, UberSets, RegSets, NormalRegs,
1732*5f7ddb14SDimitry Andric NormalUnits, RegBank);
17330b57cec5SDimitry Andric }
17340b57cec5SDimitry Andric // Postorder register normalization.
17350b57cec5SDimitry Andric
17360b57cec5SDimitry Andric // Inherit register units newly adopted by subregisters.
17370b57cec5SDimitry Andric if (Reg->inheritRegUnits(RegBank))
17380b57cec5SDimitry Andric computeUberWeights(UberSets, RegBank);
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andric // Check if this register is too skinny for its UberRegSet.
17410b57cec5SDimitry Andric UberRegSet *UberSet = RegSets[RegBank.getRegIndex(Reg)];
17420b57cec5SDimitry Andric
17430b57cec5SDimitry Andric unsigned RegWeight = Reg->getWeight(RegBank);
17440b57cec5SDimitry Andric if (UberSet->Weight > RegWeight) {
17450b57cec5SDimitry Andric // A register unit's weight can be adjusted only if it is the singular unit
17460b57cec5SDimitry Andric // for this register, has not been used to normalize a subregister's set,
17470b57cec5SDimitry Andric // and has not already been used to singularly determine this UberRegSet.
17480b57cec5SDimitry Andric unsigned AdjustUnit = *Reg->getRegUnits().begin();
17490b57cec5SDimitry Andric if (Reg->getRegUnits().count() != 1
17500b57cec5SDimitry Andric || hasRegUnit(NormalUnits, AdjustUnit)
17510b57cec5SDimitry Andric || hasRegUnit(UberSet->SingularDeterminants, AdjustUnit)) {
17520b57cec5SDimitry Andric // We don't have an adjustable unit, so adopt a new one.
17530b57cec5SDimitry Andric AdjustUnit = RegBank.newRegUnit(UberSet->Weight - RegWeight);
17540b57cec5SDimitry Andric Reg->adoptRegUnit(AdjustUnit);
17550b57cec5SDimitry Andric // Adopting a unit does not immediately require recomputing set weights.
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric else {
17580b57cec5SDimitry Andric // Adjust the existing single unit.
17590b57cec5SDimitry Andric if (!RegBank.getRegUnit(AdjustUnit).Artificial)
17600b57cec5SDimitry Andric RegBank.increaseRegUnitWeight(AdjustUnit, UberSet->Weight - RegWeight);
17610b57cec5SDimitry Andric // The unit may be shared among sets and registers within this set.
17620b57cec5SDimitry Andric computeUberWeights(UberSets, RegBank);
17630b57cec5SDimitry Andric }
17640b57cec5SDimitry Andric Changed = true;
17650b57cec5SDimitry Andric }
17660b57cec5SDimitry Andric
17670b57cec5SDimitry Andric // Mark these units normalized so superregisters can't change their weights.
17680b57cec5SDimitry Andric NormalUnits |= Reg->getRegUnits();
17690b57cec5SDimitry Andric
17700b57cec5SDimitry Andric return Changed;
17710b57cec5SDimitry Andric }
17720b57cec5SDimitry Andric
17730b57cec5SDimitry Andric // Compute a weight for each register unit created during getSubRegs.
17740b57cec5SDimitry Andric //
17750b57cec5SDimitry Andric // The goal is that two registers in the same class will have the same weight,
17760b57cec5SDimitry Andric // where each register's weight is defined as sum of its units' weights.
computeRegUnitWeights()17770b57cec5SDimitry Andric void CodeGenRegBank::computeRegUnitWeights() {
17780b57cec5SDimitry Andric std::vector<UberRegSet> UberSets;
17790b57cec5SDimitry Andric std::vector<UberRegSet*> RegSets(Registers.size());
17800b57cec5SDimitry Andric computeUberSets(UberSets, RegSets, *this);
17810b57cec5SDimitry Andric // UberSets and RegSets are now immutable.
17820b57cec5SDimitry Andric
17830b57cec5SDimitry Andric computeUberWeights(UberSets, *this);
17840b57cec5SDimitry Andric
17850b57cec5SDimitry Andric // Iterate over each Register, normalizing the unit weights until reaching
17860b57cec5SDimitry Andric // a fix point.
17870b57cec5SDimitry Andric unsigned NumIters = 0;
17880b57cec5SDimitry Andric for (bool Changed = true; Changed; ++NumIters) {
17890b57cec5SDimitry Andric assert(NumIters <= NumNativeRegUnits && "Runaway register unit weights");
17900b57cec5SDimitry Andric Changed = false;
17910b57cec5SDimitry Andric for (auto &Reg : Registers) {
17920b57cec5SDimitry Andric CodeGenRegister::RegUnitList NormalUnits;
17930b57cec5SDimitry Andric BitVector NormalRegs;
17940b57cec5SDimitry Andric Changed |= normalizeWeight(&Reg, UberSets, RegSets, NormalRegs,
17950b57cec5SDimitry Andric NormalUnits, *this);
17960b57cec5SDimitry Andric }
17970b57cec5SDimitry Andric }
17980b57cec5SDimitry Andric }
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andric // Find a set in UniqueSets with the same elements as Set.
18010b57cec5SDimitry Andric // Return an iterator into UniqueSets.
18020b57cec5SDimitry Andric static std::vector<RegUnitSet>::const_iterator
findRegUnitSet(const std::vector<RegUnitSet> & UniqueSets,const RegUnitSet & Set)18030b57cec5SDimitry Andric findRegUnitSet(const std::vector<RegUnitSet> &UniqueSets,
18040b57cec5SDimitry Andric const RegUnitSet &Set) {
18050b57cec5SDimitry Andric std::vector<RegUnitSet>::const_iterator
18060b57cec5SDimitry Andric I = UniqueSets.begin(), E = UniqueSets.end();
18070b57cec5SDimitry Andric for(;I != E; ++I) {
18080b57cec5SDimitry Andric if (I->Units == Set.Units)
18090b57cec5SDimitry Andric break;
18100b57cec5SDimitry Andric }
18110b57cec5SDimitry Andric return I;
18120b57cec5SDimitry Andric }
18130b57cec5SDimitry Andric
18140b57cec5SDimitry Andric // Return true if the RUSubSet is a subset of RUSuperSet.
isRegUnitSubSet(const std::vector<unsigned> & RUSubSet,const std::vector<unsigned> & RUSuperSet)18150b57cec5SDimitry Andric static bool isRegUnitSubSet(const std::vector<unsigned> &RUSubSet,
18160b57cec5SDimitry Andric const std::vector<unsigned> &RUSuperSet) {
18170b57cec5SDimitry Andric return std::includes(RUSuperSet.begin(), RUSuperSet.end(),
18180b57cec5SDimitry Andric RUSubSet.begin(), RUSubSet.end());
18190b57cec5SDimitry Andric }
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andric /// Iteratively prune unit sets. Prune subsets that are close to the superset,
18220b57cec5SDimitry Andric /// but with one or two registers removed. We occasionally have registers like
18230b57cec5SDimitry Andric /// APSR and PC thrown in with the general registers. We also see many
18240b57cec5SDimitry Andric /// special-purpose register subsets, such as tail-call and Thumb
18250b57cec5SDimitry Andric /// encodings. Generating all possible overlapping sets is combinatorial and
18260b57cec5SDimitry Andric /// overkill for modeling pressure. Ideally we could fix this statically in
18270b57cec5SDimitry Andric /// tablegen by (1) having the target define register classes that only include
18280b57cec5SDimitry Andric /// the allocatable registers and marking other classes as non-allocatable and
18290b57cec5SDimitry Andric /// (2) having a way to mark special purpose classes as "don't-care" classes for
18300b57cec5SDimitry Andric /// the purpose of pressure. However, we make an attempt to handle targets that
18310b57cec5SDimitry Andric /// are not nicely defined by merging nearly identical register unit sets
18320b57cec5SDimitry Andric /// statically. This generates smaller tables. Then, dynamically, we adjust the
18330b57cec5SDimitry Andric /// set limit by filtering the reserved registers.
18340b57cec5SDimitry Andric ///
18350b57cec5SDimitry Andric /// Merge sets only if the units have the same weight. For example, on ARM,
18360b57cec5SDimitry Andric /// Q-tuples with ssub index 0 include all S regs but also include D16+. We
18370b57cec5SDimitry Andric /// should not expand the S set to include D regs.
pruneUnitSets()18380b57cec5SDimitry Andric void CodeGenRegBank::pruneUnitSets() {
18390b57cec5SDimitry Andric assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets");
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andric // Form an equivalence class of UnitSets with no significant difference.
18420b57cec5SDimitry Andric std::vector<unsigned> SuperSetIDs;
18430b57cec5SDimitry Andric for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size();
18440b57cec5SDimitry Andric SubIdx != EndIdx; ++SubIdx) {
18450b57cec5SDimitry Andric const RegUnitSet &SubSet = RegUnitSets[SubIdx];
18460b57cec5SDimitry Andric unsigned SuperIdx = 0;
18470b57cec5SDimitry Andric for (; SuperIdx != EndIdx; ++SuperIdx) {
18480b57cec5SDimitry Andric if (SuperIdx == SubIdx)
18490b57cec5SDimitry Andric continue;
18500b57cec5SDimitry Andric
18510b57cec5SDimitry Andric unsigned UnitWeight = RegUnits[SubSet.Units[0]].Weight;
18520b57cec5SDimitry Andric const RegUnitSet &SuperSet = RegUnitSets[SuperIdx];
18530b57cec5SDimitry Andric if (isRegUnitSubSet(SubSet.Units, SuperSet.Units)
18540b57cec5SDimitry Andric && (SubSet.Units.size() + 3 > SuperSet.Units.size())
18550b57cec5SDimitry Andric && UnitWeight == RegUnits[SuperSet.Units[0]].Weight
18560b57cec5SDimitry Andric && UnitWeight == RegUnits[SuperSet.Units.back()].Weight) {
18570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "UnitSet " << SubIdx << " subsumed by " << SuperIdx
18580b57cec5SDimitry Andric << "\n");
18590b57cec5SDimitry Andric // We can pick any of the set names for the merged set. Go for the
18600b57cec5SDimitry Andric // shortest one to avoid picking the name of one of the classes that are
18610b57cec5SDimitry Andric // artificially created by tablegen. So "FPR128_lo" instead of
18620b57cec5SDimitry Andric // "QQQQ_with_qsub3_in_FPR128_lo".
18630b57cec5SDimitry Andric if (RegUnitSets[SubIdx].Name.size() < RegUnitSets[SuperIdx].Name.size())
18640b57cec5SDimitry Andric RegUnitSets[SuperIdx].Name = RegUnitSets[SubIdx].Name;
18650b57cec5SDimitry Andric break;
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric }
18680b57cec5SDimitry Andric if (SuperIdx == EndIdx)
18690b57cec5SDimitry Andric SuperSetIDs.push_back(SubIdx);
18700b57cec5SDimitry Andric }
18710b57cec5SDimitry Andric // Populate PrunedUnitSets with each equivalence class's superset.
18720b57cec5SDimitry Andric std::vector<RegUnitSet> PrunedUnitSets(SuperSetIDs.size());
18730b57cec5SDimitry Andric for (unsigned i = 0, e = SuperSetIDs.size(); i != e; ++i) {
18740b57cec5SDimitry Andric unsigned SuperIdx = SuperSetIDs[i];
18750b57cec5SDimitry Andric PrunedUnitSets[i].Name = RegUnitSets[SuperIdx].Name;
18760b57cec5SDimitry Andric PrunedUnitSets[i].Units.swap(RegUnitSets[SuperIdx].Units);
18770b57cec5SDimitry Andric }
18780b57cec5SDimitry Andric RegUnitSets.swap(PrunedUnitSets);
18790b57cec5SDimitry Andric }
18800b57cec5SDimitry Andric
18810b57cec5SDimitry Andric // Create a RegUnitSet for each RegClass that contains all units in the class
18820b57cec5SDimitry Andric // including adopted units that are necessary to model register pressure. Then
18830b57cec5SDimitry Andric // iteratively compute RegUnitSets such that the union of any two overlapping
18840b57cec5SDimitry Andric // RegUnitSets is repreresented.
18850b57cec5SDimitry Andric //
18860b57cec5SDimitry Andric // RegisterInfoEmitter will map each RegClass to its RegUnitClass and any
18870b57cec5SDimitry Andric // RegUnitSet that is a superset of that RegUnitClass.
computeRegUnitSets()18880b57cec5SDimitry Andric void CodeGenRegBank::computeRegUnitSets() {
18890b57cec5SDimitry Andric assert(RegUnitSets.empty() && "dirty RegUnitSets");
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andric // Compute a unique RegUnitSet for each RegClass.
18920b57cec5SDimitry Andric auto &RegClasses = getRegClasses();
18930b57cec5SDimitry Andric for (auto &RC : RegClasses) {
18945ffd83dbSDimitry Andric if (!RC.Allocatable || RC.Artificial || !RC.GeneratePressureSet)
18950b57cec5SDimitry Andric continue;
18960b57cec5SDimitry Andric
18970b57cec5SDimitry Andric // Speculatively grow the RegUnitSets to hold the new set.
18980b57cec5SDimitry Andric RegUnitSets.resize(RegUnitSets.size() + 1);
18990b57cec5SDimitry Andric RegUnitSets.back().Name = RC.getName();
19000b57cec5SDimitry Andric
19010b57cec5SDimitry Andric // Compute a sorted list of units in this class.
19020b57cec5SDimitry Andric RC.buildRegUnitSet(*this, RegUnitSets.back().Units);
19030b57cec5SDimitry Andric
19040b57cec5SDimitry Andric // Find an existing RegUnitSet.
19050b57cec5SDimitry Andric std::vector<RegUnitSet>::const_iterator SetI =
19060b57cec5SDimitry Andric findRegUnitSet(RegUnitSets, RegUnitSets.back());
19070b57cec5SDimitry Andric if (SetI != std::prev(RegUnitSets.end()))
19080b57cec5SDimitry Andric RegUnitSets.pop_back();
19090b57cec5SDimitry Andric }
19100b57cec5SDimitry Andric
19110b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\nBefore pruning:\n"; for (unsigned USIdx = 0,
19120b57cec5SDimitry Andric USEnd = RegUnitSets.size();
19130b57cec5SDimitry Andric USIdx < USEnd; ++USIdx) {
19140b57cec5SDimitry Andric dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":";
19150b57cec5SDimitry Andric for (auto &U : RegUnitSets[USIdx].Units)
19160b57cec5SDimitry Andric printRegUnitName(U);
19170b57cec5SDimitry Andric dbgs() << "\n";
19180b57cec5SDimitry Andric });
19190b57cec5SDimitry Andric
19200b57cec5SDimitry Andric // Iteratively prune unit sets.
19210b57cec5SDimitry Andric pruneUnitSets();
19220b57cec5SDimitry Andric
19230b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\nBefore union:\n"; for (unsigned USIdx = 0,
19240b57cec5SDimitry Andric USEnd = RegUnitSets.size();
19250b57cec5SDimitry Andric USIdx < USEnd; ++USIdx) {
19260b57cec5SDimitry Andric dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":";
19270b57cec5SDimitry Andric for (auto &U : RegUnitSets[USIdx].Units)
19280b57cec5SDimitry Andric printRegUnitName(U);
19290b57cec5SDimitry Andric dbgs() << "\n";
19300b57cec5SDimitry Andric } dbgs() << "\nUnion sets:\n");
19310b57cec5SDimitry Andric
19320b57cec5SDimitry Andric // Iterate over all unit sets, including new ones added by this loop.
19330b57cec5SDimitry Andric unsigned NumRegUnitSubSets = RegUnitSets.size();
19340b57cec5SDimitry Andric for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) {
19350b57cec5SDimitry Andric // In theory, this is combinatorial. In practice, it needs to be bounded
19360b57cec5SDimitry Andric // by a small number of sets for regpressure to be efficient.
19370b57cec5SDimitry Andric // If the assert is hit, we need to implement pruning.
19380b57cec5SDimitry Andric assert(Idx < (2*NumRegUnitSubSets) && "runaway unit set inference");
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric // Compare new sets with all original classes.
19410b57cec5SDimitry Andric for (unsigned SearchIdx = (Idx >= NumRegUnitSubSets) ? 0 : Idx+1;
19420b57cec5SDimitry Andric SearchIdx != EndIdx; ++SearchIdx) {
19430b57cec5SDimitry Andric std::set<unsigned> Intersection;
19440b57cec5SDimitry Andric std::set_intersection(RegUnitSets[Idx].Units.begin(),
19450b57cec5SDimitry Andric RegUnitSets[Idx].Units.end(),
19460b57cec5SDimitry Andric RegUnitSets[SearchIdx].Units.begin(),
19470b57cec5SDimitry Andric RegUnitSets[SearchIdx].Units.end(),
19480b57cec5SDimitry Andric std::inserter(Intersection, Intersection.begin()));
19490b57cec5SDimitry Andric if (Intersection.empty())
19500b57cec5SDimitry Andric continue;
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andric // Speculatively grow the RegUnitSets to hold the new set.
19530b57cec5SDimitry Andric RegUnitSets.resize(RegUnitSets.size() + 1);
19540b57cec5SDimitry Andric RegUnitSets.back().Name =
19555ffd83dbSDimitry Andric RegUnitSets[Idx].Name + "_with_" + RegUnitSets[SearchIdx].Name;
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric std::set_union(RegUnitSets[Idx].Units.begin(),
19580b57cec5SDimitry Andric RegUnitSets[Idx].Units.end(),
19590b57cec5SDimitry Andric RegUnitSets[SearchIdx].Units.begin(),
19600b57cec5SDimitry Andric RegUnitSets[SearchIdx].Units.end(),
19610b57cec5SDimitry Andric std::inserter(RegUnitSets.back().Units,
19620b57cec5SDimitry Andric RegUnitSets.back().Units.begin()));
19630b57cec5SDimitry Andric
19640b57cec5SDimitry Andric // Find an existing RegUnitSet, or add the union to the unique sets.
19650b57cec5SDimitry Andric std::vector<RegUnitSet>::const_iterator SetI =
19660b57cec5SDimitry Andric findRegUnitSet(RegUnitSets, RegUnitSets.back());
19670b57cec5SDimitry Andric if (SetI != std::prev(RegUnitSets.end()))
19680b57cec5SDimitry Andric RegUnitSets.pop_back();
19690b57cec5SDimitry Andric else {
19700b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "UnitSet " << RegUnitSets.size() - 1 << " "
19710b57cec5SDimitry Andric << RegUnitSets.back().Name << ":";
19720b57cec5SDimitry Andric for (auto &U
19730b57cec5SDimitry Andric : RegUnitSets.back().Units) printRegUnitName(U);
19740b57cec5SDimitry Andric dbgs() << "\n";);
19750b57cec5SDimitry Andric }
19760b57cec5SDimitry Andric }
19770b57cec5SDimitry Andric }
19780b57cec5SDimitry Andric
19790b57cec5SDimitry Andric // Iteratively prune unit sets after inferring supersets.
19800b57cec5SDimitry Andric pruneUnitSets();
19810b57cec5SDimitry Andric
19820b57cec5SDimitry Andric LLVM_DEBUG(
19830b57cec5SDimitry Andric dbgs() << "\n"; for (unsigned USIdx = 0, USEnd = RegUnitSets.size();
19840b57cec5SDimitry Andric USIdx < USEnd; ++USIdx) {
19850b57cec5SDimitry Andric dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":";
19860b57cec5SDimitry Andric for (auto &U : RegUnitSets[USIdx].Units)
19870b57cec5SDimitry Andric printRegUnitName(U);
19880b57cec5SDimitry Andric dbgs() << "\n";
19890b57cec5SDimitry Andric });
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andric // For each register class, list the UnitSets that are supersets.
19920b57cec5SDimitry Andric RegClassUnitSets.resize(RegClasses.size());
19930b57cec5SDimitry Andric int RCIdx = -1;
19940b57cec5SDimitry Andric for (auto &RC : RegClasses) {
19950b57cec5SDimitry Andric ++RCIdx;
19960b57cec5SDimitry Andric if (!RC.Allocatable)
19970b57cec5SDimitry Andric continue;
19980b57cec5SDimitry Andric
19990b57cec5SDimitry Andric // Recompute the sorted list of units in this class.
20000b57cec5SDimitry Andric std::vector<unsigned> RCRegUnits;
20010b57cec5SDimitry Andric RC.buildRegUnitSet(*this, RCRegUnits);
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andric // Don't increase pressure for unallocatable regclasses.
20040b57cec5SDimitry Andric if (RCRegUnits.empty())
20050b57cec5SDimitry Andric continue;
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "RC " << RC.getName() << " Units:\n";
20080b57cec5SDimitry Andric for (auto U
20090b57cec5SDimitry Andric : RCRegUnits) printRegUnitName(U);
20100b57cec5SDimitry Andric dbgs() << "\n UnitSetIDs:");
20110b57cec5SDimitry Andric
20120b57cec5SDimitry Andric // Find all supersets.
20130b57cec5SDimitry Andric for (unsigned USIdx = 0, USEnd = RegUnitSets.size();
20140b57cec5SDimitry Andric USIdx != USEnd; ++USIdx) {
20150b57cec5SDimitry Andric if (isRegUnitSubSet(RCRegUnits, RegUnitSets[USIdx].Units)) {
20160b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " " << USIdx);
20170b57cec5SDimitry Andric RegClassUnitSets[RCIdx].push_back(USIdx);
20180b57cec5SDimitry Andric }
20190b57cec5SDimitry Andric }
20200b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\n");
20210b57cec5SDimitry Andric assert(!RegClassUnitSets[RCIdx].empty() && "missing unit set for regclass");
20220b57cec5SDimitry Andric }
20230b57cec5SDimitry Andric
20240b57cec5SDimitry Andric // For each register unit, ensure that we have the list of UnitSets that
20250b57cec5SDimitry Andric // contain the unit. Normally, this matches an existing list of UnitSets for a
20260b57cec5SDimitry Andric // register class. If not, we create a new entry in RegClassUnitSets as a
20270b57cec5SDimitry Andric // "fake" register class.
20280b57cec5SDimitry Andric for (unsigned UnitIdx = 0, UnitEnd = NumNativeRegUnits;
20290b57cec5SDimitry Andric UnitIdx < UnitEnd; ++UnitIdx) {
20300b57cec5SDimitry Andric std::vector<unsigned> RUSets;
20310b57cec5SDimitry Andric for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) {
20320b57cec5SDimitry Andric RegUnitSet &RUSet = RegUnitSets[i];
20330b57cec5SDimitry Andric if (!is_contained(RUSet.Units, UnitIdx))
20340b57cec5SDimitry Andric continue;
20350b57cec5SDimitry Andric RUSets.push_back(i);
20360b57cec5SDimitry Andric }
20370b57cec5SDimitry Andric unsigned RCUnitSetsIdx = 0;
20380b57cec5SDimitry Andric for (unsigned e = RegClassUnitSets.size();
20390b57cec5SDimitry Andric RCUnitSetsIdx != e; ++RCUnitSetsIdx) {
20400b57cec5SDimitry Andric if (RegClassUnitSets[RCUnitSetsIdx] == RUSets) {
20410b57cec5SDimitry Andric break;
20420b57cec5SDimitry Andric }
20430b57cec5SDimitry Andric }
20440b57cec5SDimitry Andric RegUnits[UnitIdx].RegClassUnitSetsIdx = RCUnitSetsIdx;
20450b57cec5SDimitry Andric if (RCUnitSetsIdx == RegClassUnitSets.size()) {
20460b57cec5SDimitry Andric // Create a new list of UnitSets as a "fake" register class.
20470b57cec5SDimitry Andric RegClassUnitSets.resize(RCUnitSetsIdx + 1);
20480b57cec5SDimitry Andric RegClassUnitSets[RCUnitSetsIdx].swap(RUSets);
20490b57cec5SDimitry Andric }
20500b57cec5SDimitry Andric }
20510b57cec5SDimitry Andric }
20520b57cec5SDimitry Andric
computeRegUnitLaneMasks()20530b57cec5SDimitry Andric void CodeGenRegBank::computeRegUnitLaneMasks() {
20540b57cec5SDimitry Andric for (auto &Register : Registers) {
20550b57cec5SDimitry Andric // Create an initial lane mask for all register units.
20560b57cec5SDimitry Andric const auto &RegUnits = Register.getRegUnits();
20570b57cec5SDimitry Andric CodeGenRegister::RegUnitLaneMaskList
20580b57cec5SDimitry Andric RegUnitLaneMasks(RegUnits.count(), LaneBitmask::getNone());
20590b57cec5SDimitry Andric // Iterate through SubRegisters.
20600b57cec5SDimitry Andric typedef CodeGenRegister::SubRegMap SubRegMap;
20610b57cec5SDimitry Andric const SubRegMap &SubRegs = Register.getSubRegs();
2062*5f7ddb14SDimitry Andric for (auto S : SubRegs) {
2063*5f7ddb14SDimitry Andric CodeGenRegister *SubReg = S.second;
20640b57cec5SDimitry Andric // Ignore non-leaf subregisters, their lane masks are fully covered by
20650b57cec5SDimitry Andric // the leaf subregisters anyway.
20660b57cec5SDimitry Andric if (!SubReg->getSubRegs().empty())
20670b57cec5SDimitry Andric continue;
2068*5f7ddb14SDimitry Andric CodeGenSubRegIndex *SubRegIndex = S.first;
2069*5f7ddb14SDimitry Andric const CodeGenRegister *SubRegister = S.second;
20700b57cec5SDimitry Andric LaneBitmask LaneMask = SubRegIndex->LaneMask;
20710b57cec5SDimitry Andric // Distribute LaneMask to Register Units touched.
20720b57cec5SDimitry Andric for (unsigned SUI : SubRegister->getRegUnits()) {
20730b57cec5SDimitry Andric bool Found = false;
20740b57cec5SDimitry Andric unsigned u = 0;
20750b57cec5SDimitry Andric for (unsigned RU : RegUnits) {
20760b57cec5SDimitry Andric if (SUI == RU) {
20770b57cec5SDimitry Andric RegUnitLaneMasks[u] |= LaneMask;
20780b57cec5SDimitry Andric assert(!Found);
20790b57cec5SDimitry Andric Found = true;
20800b57cec5SDimitry Andric }
20810b57cec5SDimitry Andric ++u;
20820b57cec5SDimitry Andric }
20830b57cec5SDimitry Andric (void)Found;
20840b57cec5SDimitry Andric assert(Found);
20850b57cec5SDimitry Andric }
20860b57cec5SDimitry Andric }
20870b57cec5SDimitry Andric Register.setRegUnitLaneMasks(RegUnitLaneMasks);
20880b57cec5SDimitry Andric }
20890b57cec5SDimitry Andric }
20900b57cec5SDimitry Andric
computeDerivedInfo()20910b57cec5SDimitry Andric void CodeGenRegBank::computeDerivedInfo() {
20920b57cec5SDimitry Andric computeComposites();
20930b57cec5SDimitry Andric computeSubRegLaneMasks();
20940b57cec5SDimitry Andric
20950b57cec5SDimitry Andric // Compute a weight for each register unit created during getSubRegs.
20960b57cec5SDimitry Andric // This may create adopted register units (with unit # >= NumNativeRegUnits).
20970b57cec5SDimitry Andric computeRegUnitWeights();
20980b57cec5SDimitry Andric
20990b57cec5SDimitry Andric // Compute a unique set of RegUnitSets. One for each RegClass and inferred
21000b57cec5SDimitry Andric // supersets for the union of overlapping sets.
21010b57cec5SDimitry Andric computeRegUnitSets();
21020b57cec5SDimitry Andric
21030b57cec5SDimitry Andric computeRegUnitLaneMasks();
21040b57cec5SDimitry Andric
21050b57cec5SDimitry Andric // Compute register class HasDisjunctSubRegs/CoveredBySubRegs flag.
21060b57cec5SDimitry Andric for (CodeGenRegisterClass &RC : RegClasses) {
21070b57cec5SDimitry Andric RC.HasDisjunctSubRegs = false;
21080b57cec5SDimitry Andric RC.CoveredBySubRegs = true;
21090b57cec5SDimitry Andric for (const CodeGenRegister *Reg : RC.getMembers()) {
21100b57cec5SDimitry Andric RC.HasDisjunctSubRegs |= Reg->HasDisjunctSubRegs;
21110b57cec5SDimitry Andric RC.CoveredBySubRegs &= Reg->CoveredBySubRegs;
21120b57cec5SDimitry Andric }
21130b57cec5SDimitry Andric }
21140b57cec5SDimitry Andric
21150b57cec5SDimitry Andric // Get the weight of each set.
21160b57cec5SDimitry Andric for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx)
21170b57cec5SDimitry Andric RegUnitSets[Idx].Weight = getRegUnitSetWeight(RegUnitSets[Idx].Units);
21180b57cec5SDimitry Andric
21190b57cec5SDimitry Andric // Find the order of each set.
21200b57cec5SDimitry Andric RegUnitSetOrder.reserve(RegUnitSets.size());
21210b57cec5SDimitry Andric for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx)
21220b57cec5SDimitry Andric RegUnitSetOrder.push_back(Idx);
21230b57cec5SDimitry Andric
21240b57cec5SDimitry Andric llvm::stable_sort(RegUnitSetOrder, [this](unsigned ID1, unsigned ID2) {
21250b57cec5SDimitry Andric return getRegPressureSet(ID1).Units.size() <
21260b57cec5SDimitry Andric getRegPressureSet(ID2).Units.size();
21270b57cec5SDimitry Andric });
21280b57cec5SDimitry Andric for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) {
21290b57cec5SDimitry Andric RegUnitSets[RegUnitSetOrder[Idx]].Order = Idx;
21300b57cec5SDimitry Andric }
21310b57cec5SDimitry Andric }
21320b57cec5SDimitry Andric
21330b57cec5SDimitry Andric //
21340b57cec5SDimitry Andric // Synthesize missing register class intersections.
21350b57cec5SDimitry Andric //
21360b57cec5SDimitry Andric // Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X)
21370b57cec5SDimitry Andric // returns a maximal register class for all X.
21380b57cec5SDimitry Andric //
inferCommonSubClass(CodeGenRegisterClass * RC)21390b57cec5SDimitry Andric void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
21400b57cec5SDimitry Andric assert(!RegClasses.empty());
21410b57cec5SDimitry Andric // Stash the iterator to the last element so that this loop doesn't visit
21420b57cec5SDimitry Andric // elements added by the getOrCreateSubClass call within it.
21430b57cec5SDimitry Andric for (auto I = RegClasses.begin(), E = std::prev(RegClasses.end());
21440b57cec5SDimitry Andric I != std::next(E); ++I) {
21450b57cec5SDimitry Andric CodeGenRegisterClass *RC1 = RC;
21460b57cec5SDimitry Andric CodeGenRegisterClass *RC2 = &*I;
21470b57cec5SDimitry Andric if (RC1 == RC2)
21480b57cec5SDimitry Andric continue;
21490b57cec5SDimitry Andric
21500b57cec5SDimitry Andric // Compute the set intersection of RC1 and RC2.
21510b57cec5SDimitry Andric const CodeGenRegister::Vec &Memb1 = RC1->getMembers();
21520b57cec5SDimitry Andric const CodeGenRegister::Vec &Memb2 = RC2->getMembers();
21530b57cec5SDimitry Andric CodeGenRegister::Vec Intersection;
21548bcb0991SDimitry Andric std::set_intersection(Memb1.begin(), Memb1.end(), Memb2.begin(),
21558bcb0991SDimitry Andric Memb2.end(),
21568bcb0991SDimitry Andric std::inserter(Intersection, Intersection.begin()),
21578bcb0991SDimitry Andric deref<std::less<>>());
21580b57cec5SDimitry Andric
21590b57cec5SDimitry Andric // Skip disjoint class pairs.
21600b57cec5SDimitry Andric if (Intersection.empty())
21610b57cec5SDimitry Andric continue;
21620b57cec5SDimitry Andric
21630b57cec5SDimitry Andric // If RC1 and RC2 have different spill sizes or alignments, use the
21640b57cec5SDimitry Andric // stricter one for sub-classing. If they are equal, prefer RC1.
21650b57cec5SDimitry Andric if (RC2->RSI.hasStricterSpillThan(RC1->RSI))
21660b57cec5SDimitry Andric std::swap(RC1, RC2);
21670b57cec5SDimitry Andric
21680b57cec5SDimitry Andric getOrCreateSubClass(RC1, &Intersection,
21690b57cec5SDimitry Andric RC1->getName() + "_and_" + RC2->getName());
21700b57cec5SDimitry Andric }
21710b57cec5SDimitry Andric }
21720b57cec5SDimitry Andric
21730b57cec5SDimitry Andric //
21740b57cec5SDimitry Andric // Synthesize missing sub-classes for getSubClassWithSubReg().
21750b57cec5SDimitry Andric //
21760b57cec5SDimitry Andric // Make sure that the set of registers in RC with a given SubIdx sub-register
21770b57cec5SDimitry Andric // form a register class. Update RC->SubClassWithSubReg.
21780b57cec5SDimitry Andric //
inferSubClassWithSubReg(CodeGenRegisterClass * RC)21790b57cec5SDimitry Andric void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
21800b57cec5SDimitry Andric // Map SubRegIndex to set of registers in RC supporting that SubRegIndex.
21810b57cec5SDimitry Andric typedef std::map<const CodeGenSubRegIndex *, CodeGenRegister::Vec,
21828bcb0991SDimitry Andric deref<std::less<>>>
21838bcb0991SDimitry Andric SubReg2SetMap;
21840b57cec5SDimitry Andric
21850b57cec5SDimitry Andric // Compute the set of registers supporting each SubRegIndex.
21860b57cec5SDimitry Andric SubReg2SetMap SRSets;
21870b57cec5SDimitry Andric for (const auto R : RC->getMembers()) {
21880b57cec5SDimitry Andric if (R->Artificial)
21890b57cec5SDimitry Andric continue;
21900b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &SRM = R->getSubRegs();
2191*5f7ddb14SDimitry Andric for (auto I : SRM) {
2192*5f7ddb14SDimitry Andric if (!I.first->Artificial)
2193*5f7ddb14SDimitry Andric SRSets[I.first].push_back(R);
21940b57cec5SDimitry Andric }
21950b57cec5SDimitry Andric }
21960b57cec5SDimitry Andric
21970b57cec5SDimitry Andric for (auto I : SRSets)
21980b57cec5SDimitry Andric sortAndUniqueRegisters(I.second);
21990b57cec5SDimitry Andric
22000b57cec5SDimitry Andric // Find matching classes for all SRSets entries. Iterate in SubRegIndex
22010b57cec5SDimitry Andric // numerical order to visit synthetic indices last.
22020b57cec5SDimitry Andric for (const auto &SubIdx : SubRegIndices) {
22030b57cec5SDimitry Andric if (SubIdx.Artificial)
22040b57cec5SDimitry Andric continue;
22050b57cec5SDimitry Andric SubReg2SetMap::const_iterator I = SRSets.find(&SubIdx);
22060b57cec5SDimitry Andric // Unsupported SubRegIndex. Skip it.
22070b57cec5SDimitry Andric if (I == SRSets.end())
22080b57cec5SDimitry Andric continue;
22090b57cec5SDimitry Andric // In most cases, all RC registers support the SubRegIndex.
22100b57cec5SDimitry Andric if (I->second.size() == RC->getMembers().size()) {
22110b57cec5SDimitry Andric RC->setSubClassWithSubReg(&SubIdx, RC);
22120b57cec5SDimitry Andric continue;
22130b57cec5SDimitry Andric }
22140b57cec5SDimitry Andric // This is a real subset. See if we have a matching class.
22150b57cec5SDimitry Andric CodeGenRegisterClass *SubRC =
22160b57cec5SDimitry Andric getOrCreateSubClass(RC, &I->second,
22170b57cec5SDimitry Andric RC->getName() + "_with_" + I->first->getName());
22180b57cec5SDimitry Andric RC->setSubClassWithSubReg(&SubIdx, SubRC);
22190b57cec5SDimitry Andric }
22200b57cec5SDimitry Andric }
22210b57cec5SDimitry Andric
22220b57cec5SDimitry Andric //
22230b57cec5SDimitry Andric // Synthesize missing sub-classes of RC for getMatchingSuperRegClass().
22240b57cec5SDimitry Andric //
22250b57cec5SDimitry Andric // Create sub-classes of RC such that getMatchingSuperRegClass(RC, SubIdx, X)
22260b57cec5SDimitry Andric // has a maximal result for any SubIdx and any X >= FirstSubRegRC.
22270b57cec5SDimitry Andric //
22280b57cec5SDimitry Andric
inferMatchingSuperRegClass(CodeGenRegisterClass * RC,std::list<CodeGenRegisterClass>::iterator FirstSubRegRC)22290b57cec5SDimitry Andric void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
22300b57cec5SDimitry Andric std::list<CodeGenRegisterClass>::iterator FirstSubRegRC) {
22310b57cec5SDimitry Andric SmallVector<std::pair<const CodeGenRegister*,
22320b57cec5SDimitry Andric const CodeGenRegister*>, 16> SSPairs;
22330b57cec5SDimitry Andric BitVector TopoSigs(getNumTopoSigs());
22340b57cec5SDimitry Andric
22350b57cec5SDimitry Andric // Iterate in SubRegIndex numerical order to visit synthetic indices last.
22360b57cec5SDimitry Andric for (auto &SubIdx : SubRegIndices) {
22370b57cec5SDimitry Andric // Skip indexes that aren't fully supported by RC's registers. This was
22380b57cec5SDimitry Andric // computed by inferSubClassWithSubReg() above which should have been
22390b57cec5SDimitry Andric // called first.
22400b57cec5SDimitry Andric if (RC->getSubClassWithSubReg(&SubIdx) != RC)
22410b57cec5SDimitry Andric continue;
22420b57cec5SDimitry Andric
22430b57cec5SDimitry Andric // Build list of (Super, Sub) pairs for this SubIdx.
22440b57cec5SDimitry Andric SSPairs.clear();
22450b57cec5SDimitry Andric TopoSigs.reset();
22460b57cec5SDimitry Andric for (const auto Super : RC->getMembers()) {
22470b57cec5SDimitry Andric const CodeGenRegister *Sub = Super->getSubRegs().find(&SubIdx)->second;
22480b57cec5SDimitry Andric assert(Sub && "Missing sub-register");
22490b57cec5SDimitry Andric SSPairs.push_back(std::make_pair(Super, Sub));
22500b57cec5SDimitry Andric TopoSigs.set(Sub->getTopoSig());
22510b57cec5SDimitry Andric }
22520b57cec5SDimitry Andric
22530b57cec5SDimitry Andric // Iterate over sub-register class candidates. Ignore classes created by
22540b57cec5SDimitry Andric // this loop. They will never be useful.
22550b57cec5SDimitry Andric // Store an iterator to the last element (not end) so that this loop doesn't
22560b57cec5SDimitry Andric // visit newly inserted elements.
22570b57cec5SDimitry Andric assert(!RegClasses.empty());
22580b57cec5SDimitry Andric for (auto I = FirstSubRegRC, E = std::prev(RegClasses.end());
22590b57cec5SDimitry Andric I != std::next(E); ++I) {
22600b57cec5SDimitry Andric CodeGenRegisterClass &SubRC = *I;
22610b57cec5SDimitry Andric if (SubRC.Artificial)
22620b57cec5SDimitry Andric continue;
22630b57cec5SDimitry Andric // Topological shortcut: SubRC members have the wrong shape.
22640b57cec5SDimitry Andric if (!TopoSigs.anyCommon(SubRC.getTopoSigs()))
22650b57cec5SDimitry Andric continue;
22660b57cec5SDimitry Andric // Compute the subset of RC that maps into SubRC.
22670b57cec5SDimitry Andric CodeGenRegister::Vec SubSetVec;
22680b57cec5SDimitry Andric for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
22690b57cec5SDimitry Andric if (SubRC.contains(SSPairs[i].second))
22700b57cec5SDimitry Andric SubSetVec.push_back(SSPairs[i].first);
22710b57cec5SDimitry Andric
22720b57cec5SDimitry Andric if (SubSetVec.empty())
22730b57cec5SDimitry Andric continue;
22740b57cec5SDimitry Andric
22750b57cec5SDimitry Andric // RC injects completely into SubRC.
22760b57cec5SDimitry Andric sortAndUniqueRegisters(SubSetVec);
22770b57cec5SDimitry Andric if (SubSetVec.size() == SSPairs.size()) {
22780b57cec5SDimitry Andric SubRC.addSuperRegClass(&SubIdx, RC);
22790b57cec5SDimitry Andric continue;
22800b57cec5SDimitry Andric }
22810b57cec5SDimitry Andric
22820b57cec5SDimitry Andric // Only a subset of RC maps into SubRC. Make sure it is represented by a
22830b57cec5SDimitry Andric // class.
22840b57cec5SDimitry Andric getOrCreateSubClass(RC, &SubSetVec, RC->getName() + "_with_" +
22850b57cec5SDimitry Andric SubIdx.getName() + "_in_" +
22860b57cec5SDimitry Andric SubRC.getName());
22870b57cec5SDimitry Andric }
22880b57cec5SDimitry Andric }
22890b57cec5SDimitry Andric }
22900b57cec5SDimitry Andric
22910b57cec5SDimitry Andric //
22920b57cec5SDimitry Andric // Infer missing register classes.
22930b57cec5SDimitry Andric //
computeInferredRegisterClasses()22940b57cec5SDimitry Andric void CodeGenRegBank::computeInferredRegisterClasses() {
22950b57cec5SDimitry Andric assert(!RegClasses.empty());
22960b57cec5SDimitry Andric // When this function is called, the register classes have not been sorted
22970b57cec5SDimitry Andric // and assigned EnumValues yet. That means getSubClasses(),
22980b57cec5SDimitry Andric // getSuperClasses(), and hasSubClass() functions are defunct.
22990b57cec5SDimitry Andric
23000b57cec5SDimitry Andric // Use one-before-the-end so it doesn't move forward when new elements are
23010b57cec5SDimitry Andric // added.
23020b57cec5SDimitry Andric auto FirstNewRC = std::prev(RegClasses.end());
23030b57cec5SDimitry Andric
23040b57cec5SDimitry Andric // Visit all register classes, including the ones being added by the loop.
23050b57cec5SDimitry Andric // Watch out for iterator invalidation here.
23060b57cec5SDimitry Andric for (auto I = RegClasses.begin(), E = RegClasses.end(); I != E; ++I) {
23070b57cec5SDimitry Andric CodeGenRegisterClass *RC = &*I;
23080b57cec5SDimitry Andric if (RC->Artificial)
23090b57cec5SDimitry Andric continue;
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andric // Synthesize answers for getSubClassWithSubReg().
23120b57cec5SDimitry Andric inferSubClassWithSubReg(RC);
23130b57cec5SDimitry Andric
23140b57cec5SDimitry Andric // Synthesize answers for getCommonSubClass().
23150b57cec5SDimitry Andric inferCommonSubClass(RC);
23160b57cec5SDimitry Andric
23170b57cec5SDimitry Andric // Synthesize answers for getMatchingSuperRegClass().
23180b57cec5SDimitry Andric inferMatchingSuperRegClass(RC);
23190b57cec5SDimitry Andric
23200b57cec5SDimitry Andric // New register classes are created while this loop is running, and we need
23210b57cec5SDimitry Andric // to visit all of them. I particular, inferMatchingSuperRegClass needs
23220b57cec5SDimitry Andric // to match old super-register classes with sub-register classes created
23230b57cec5SDimitry Andric // after inferMatchingSuperRegClass was called. At this point,
23240b57cec5SDimitry Andric // inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC =
23250b57cec5SDimitry Andric // [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci].
23260b57cec5SDimitry Andric if (I == FirstNewRC) {
23270b57cec5SDimitry Andric auto NextNewRC = std::prev(RegClasses.end());
23280b57cec5SDimitry Andric for (auto I2 = RegClasses.begin(), E2 = std::next(FirstNewRC); I2 != E2;
23290b57cec5SDimitry Andric ++I2)
23300b57cec5SDimitry Andric inferMatchingSuperRegClass(&*I2, E2);
23310b57cec5SDimitry Andric FirstNewRC = NextNewRC;
23320b57cec5SDimitry Andric }
23330b57cec5SDimitry Andric }
23340b57cec5SDimitry Andric }
23350b57cec5SDimitry Andric
23360b57cec5SDimitry Andric /// getRegisterClassForRegister - Find the register class that contains the
23370b57cec5SDimitry Andric /// specified physical register. If the register is not in a register class,
23380b57cec5SDimitry Andric /// return null. If the register is in multiple classes, and the classes have a
23390b57cec5SDimitry Andric /// superset-subset relationship and the same set of types, return the
23400b57cec5SDimitry Andric /// superclass. Otherwise return null.
23410b57cec5SDimitry Andric const CodeGenRegisterClass*
getRegClassForRegister(Record * R)23420b57cec5SDimitry Andric CodeGenRegBank::getRegClassForRegister(Record *R) {
23430b57cec5SDimitry Andric const CodeGenRegister *Reg = getReg(R);
23440b57cec5SDimitry Andric const CodeGenRegisterClass *FoundRC = nullptr;
23450b57cec5SDimitry Andric for (const auto &RC : getRegClasses()) {
23460b57cec5SDimitry Andric if (!RC.contains(Reg))
23470b57cec5SDimitry Andric continue;
23480b57cec5SDimitry Andric
23490b57cec5SDimitry Andric // If this is the first class that contains the register,
23500b57cec5SDimitry Andric // make a note of it and go on to the next class.
23510b57cec5SDimitry Andric if (!FoundRC) {
23520b57cec5SDimitry Andric FoundRC = &RC;
23530b57cec5SDimitry Andric continue;
23540b57cec5SDimitry Andric }
23550b57cec5SDimitry Andric
23560b57cec5SDimitry Andric // If a register's classes have different types, return null.
23570b57cec5SDimitry Andric if (RC.getValueTypes() != FoundRC->getValueTypes())
23580b57cec5SDimitry Andric return nullptr;
23590b57cec5SDimitry Andric
23600b57cec5SDimitry Andric // Check to see if the previously found class that contains
23610b57cec5SDimitry Andric // the register is a subclass of the current class. If so,
23620b57cec5SDimitry Andric // prefer the superclass.
23630b57cec5SDimitry Andric if (RC.hasSubClass(FoundRC)) {
23640b57cec5SDimitry Andric FoundRC = &RC;
23650b57cec5SDimitry Andric continue;
23660b57cec5SDimitry Andric }
23670b57cec5SDimitry Andric
23680b57cec5SDimitry Andric // Check to see if the previously found class that contains
23690b57cec5SDimitry Andric // the register is a superclass of the current class. If so,
23700b57cec5SDimitry Andric // prefer the superclass.
23710b57cec5SDimitry Andric if (FoundRC->hasSubClass(&RC))
23720b57cec5SDimitry Andric continue;
23730b57cec5SDimitry Andric
23740b57cec5SDimitry Andric // Multiple classes, and neither is a superclass of the other.
23750b57cec5SDimitry Andric // Return null.
23760b57cec5SDimitry Andric return nullptr;
23770b57cec5SDimitry Andric }
23780b57cec5SDimitry Andric return FoundRC;
23790b57cec5SDimitry Andric }
23800b57cec5SDimitry Andric
23818bcb0991SDimitry Andric const CodeGenRegisterClass *
getMinimalPhysRegClass(Record * RegRecord,ValueTypeByHwMode * VT)23828bcb0991SDimitry Andric CodeGenRegBank::getMinimalPhysRegClass(Record *RegRecord,
23838bcb0991SDimitry Andric ValueTypeByHwMode *VT) {
23848bcb0991SDimitry Andric const CodeGenRegister *Reg = getReg(RegRecord);
23858bcb0991SDimitry Andric const CodeGenRegisterClass *BestRC = nullptr;
23868bcb0991SDimitry Andric for (const auto &RC : getRegClasses()) {
23878bcb0991SDimitry Andric if ((!VT || RC.hasType(*VT)) &&
23888bcb0991SDimitry Andric RC.contains(Reg) && (!BestRC || BestRC->hasSubClass(&RC)))
23898bcb0991SDimitry Andric BestRC = &RC;
23908bcb0991SDimitry Andric }
23918bcb0991SDimitry Andric
23928bcb0991SDimitry Andric assert(BestRC && "Couldn't find the register class");
23938bcb0991SDimitry Andric return BestRC;
23948bcb0991SDimitry Andric }
23958bcb0991SDimitry Andric
computeCoveredRegisters(ArrayRef<Record * > Regs)23960b57cec5SDimitry Andric BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef<Record*> Regs) {
23970b57cec5SDimitry Andric SetVector<const CodeGenRegister*> Set;
23980b57cec5SDimitry Andric
23990b57cec5SDimitry Andric // First add Regs with all sub-registers.
24000b57cec5SDimitry Andric for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
24010b57cec5SDimitry Andric CodeGenRegister *Reg = getReg(Regs[i]);
24020b57cec5SDimitry Andric if (Set.insert(Reg))
24030b57cec5SDimitry Andric // Reg is new, add all sub-registers.
24040b57cec5SDimitry Andric // The pre-ordering is not important here.
24050b57cec5SDimitry Andric Reg->addSubRegsPreOrder(Set, *this);
24060b57cec5SDimitry Andric }
24070b57cec5SDimitry Andric
24080b57cec5SDimitry Andric // Second, find all super-registers that are completely covered by the set.
24090b57cec5SDimitry Andric for (unsigned i = 0; i != Set.size(); ++i) {
24100b57cec5SDimitry Andric const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs();
24110b57cec5SDimitry Andric for (unsigned j = 0, e = SR.size(); j != e; ++j) {
24120b57cec5SDimitry Andric const CodeGenRegister *Super = SR[j];
24130b57cec5SDimitry Andric if (!Super->CoveredBySubRegs || Set.count(Super))
24140b57cec5SDimitry Andric continue;
24150b57cec5SDimitry Andric // This new super-register is covered by its sub-registers.
24160b57cec5SDimitry Andric bool AllSubsInSet = true;
24170b57cec5SDimitry Andric const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs();
2418*5f7ddb14SDimitry Andric for (auto I : SRM)
2419*5f7ddb14SDimitry Andric if (!Set.count(I.second)) {
24200b57cec5SDimitry Andric AllSubsInSet = false;
24210b57cec5SDimitry Andric break;
24220b57cec5SDimitry Andric }
24230b57cec5SDimitry Andric // All sub-registers in Set, add Super as well.
24240b57cec5SDimitry Andric // We will visit Super later to recheck its super-registers.
24250b57cec5SDimitry Andric if (AllSubsInSet)
24260b57cec5SDimitry Andric Set.insert(Super);
24270b57cec5SDimitry Andric }
24280b57cec5SDimitry Andric }
24290b57cec5SDimitry Andric
24300b57cec5SDimitry Andric // Convert to BitVector.
24310b57cec5SDimitry Andric BitVector BV(Registers.size() + 1);
24320b57cec5SDimitry Andric for (unsigned i = 0, e = Set.size(); i != e; ++i)
24330b57cec5SDimitry Andric BV.set(Set[i]->EnumValue);
24340b57cec5SDimitry Andric return BV;
24350b57cec5SDimitry Andric }
24360b57cec5SDimitry Andric
printRegUnitName(unsigned Unit) const24370b57cec5SDimitry Andric void CodeGenRegBank::printRegUnitName(unsigned Unit) const {
24380b57cec5SDimitry Andric if (Unit < NumNativeRegUnits)
24390b57cec5SDimitry Andric dbgs() << ' ' << RegUnits[Unit].Roots[0]->getName();
24400b57cec5SDimitry Andric else
24410b57cec5SDimitry Andric dbgs() << " #" << Unit;
24420b57cec5SDimitry Andric }
2443