1fa3d789dSPierre van Houtryve //===- CodeGenRegisters.cpp - Register and RegisterClass Info -------------===// 2fa3d789dSPierre van Houtryve // 3fa3d789dSPierre van Houtryve // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fa3d789dSPierre van Houtryve // See https://llvm.org/LICENSE.txt for license information. 5fa3d789dSPierre van Houtryve // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fa3d789dSPierre van Houtryve // 7fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 8fa3d789dSPierre van Houtryve // 9fa3d789dSPierre van Houtryve // This file defines structures to encapsulate information gleaned from the 10fa3d789dSPierre van Houtryve // target register and register class definitions. 11fa3d789dSPierre van Houtryve // 12fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 13fa3d789dSPierre van Houtryve 14fa3d789dSPierre van Houtryve #include "CodeGenRegisters.h" 15fa3d789dSPierre van Houtryve #include "llvm/ADT/ArrayRef.h" 16fa3d789dSPierre van Houtryve #include "llvm/ADT/BitVector.h" 17fa3d789dSPierre van Houtryve #include "llvm/ADT/DenseMap.h" 18fa3d789dSPierre van Houtryve #include "llvm/ADT/IntEqClasses.h" 19fa3d789dSPierre van Houtryve #include "llvm/ADT/STLExtras.h" 20fa3d789dSPierre van Houtryve #include "llvm/ADT/SetVector.h" 21fa3d789dSPierre van Houtryve #include "llvm/ADT/SmallPtrSet.h" 22fa3d789dSPierre van Houtryve #include "llvm/ADT/SmallSet.h" 23fa3d789dSPierre van Houtryve #include "llvm/ADT/SmallVector.h" 24fa3d789dSPierre van Houtryve #include "llvm/ADT/StringRef.h" 25edf5782fSJason Eckhardt #include "llvm/ADT/StringSet.h" 26fa3d789dSPierre van Houtryve #include "llvm/ADT/Twine.h" 27fa3d789dSPierre van Houtryve #include "llvm/Support/Debug.h" 28fa3d789dSPierre van Houtryve #include "llvm/Support/raw_ostream.h" 29fa3d789dSPierre van Houtryve #include "llvm/TableGen/Error.h" 30fa3d789dSPierre van Houtryve #include "llvm/TableGen/Record.h" 31fa3d789dSPierre van Houtryve #include <algorithm> 32fa3d789dSPierre van Houtryve #include <cassert> 33fa3d789dSPierre van Houtryve #include <cstdint> 34fa3d789dSPierre van Houtryve #include <iterator> 35fa3d789dSPierre van Houtryve #include <map> 36fa3d789dSPierre van Houtryve #include <queue> 37fa3d789dSPierre van Houtryve #include <string> 38fa3d789dSPierre van Houtryve #include <tuple> 39fa3d789dSPierre van Houtryve #include <utility> 40fa3d789dSPierre van Houtryve #include <vector> 41fa3d789dSPierre van Houtryve 42fa3d789dSPierre van Houtryve using namespace llvm; 43fa3d789dSPierre van Houtryve 44fa3d789dSPierre van Houtryve #define DEBUG_TYPE "regalloc-emitter" 45fa3d789dSPierre van Houtryve 46fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 47fa3d789dSPierre van Houtryve // CodeGenSubRegIndex 48fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 49fa3d789dSPierre van Houtryve 507c6592f5SRahul Joshi CodeGenSubRegIndex::CodeGenSubRegIndex(const Record *R, unsigned Enum, 51baf66ec0SCraig Topper const CodeGenHwModes &CGH) 52fa3d789dSPierre van Houtryve : TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) { 53fa3d789dSPierre van Houtryve Name = std::string(R->getName()); 54fa3d789dSPierre van Houtryve if (R->getValue("Namespace")) 55fa3d789dSPierre van Houtryve Namespace = std::string(R->getValueAsString("Namespace")); 56baf66ec0SCraig Topper 57baf66ec0SCraig Topper if (const RecordVal *RV = R->getValue("SubRegRanges")) 58baf66ec0SCraig Topper if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) 59baf66ec0SCraig Topper Range = SubRegRangeByHwMode(DI->getDef(), CGH); 60baf66ec0SCraig Topper if (!Range.hasDefault()) 61baf66ec0SCraig Topper Range.insertSubRegRangeForMode(DefaultMode, SubRegRange(R)); 62fa3d789dSPierre van Houtryve } 63fa3d789dSPierre van Houtryve 64fa3d789dSPierre van Houtryve CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, 65fa3d789dSPierre van Houtryve unsigned Enum) 66fa3d789dSPierre van Houtryve : TheDef(nullptr), Name(std::string(N)), Namespace(std::string(Nspace)), 67baf66ec0SCraig Topper Range(SubRegRange(-1, -1)), EnumValue(Enum), AllSuperRegsCovered(true), 68fa3d789dSPierre van Houtryve Artificial(true) {} 69fa3d789dSPierre van Houtryve 70fa3d789dSPierre van Houtryve std::string CodeGenSubRegIndex::getQualifiedName() const { 71fa3d789dSPierre van Houtryve std::string N = getNamespace(); 72fa3d789dSPierre van Houtryve if (!N.empty()) 73fa3d789dSPierre van Houtryve N += "::"; 74fa3d789dSPierre van Houtryve N += getName(); 75fa3d789dSPierre van Houtryve return N; 76fa3d789dSPierre van Houtryve } 77fa3d789dSPierre van Houtryve 78fa3d789dSPierre van Houtryve void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { 79fa3d789dSPierre van Houtryve if (!TheDef) 80fa3d789dSPierre van Houtryve return; 81fa3d789dSPierre van Houtryve 823138eb50SRahul Joshi std::vector<const Record *> Comps = 83a140931bSRahul Joshi TheDef->getValueAsListOfDefs("ComposedOf"); 84fa3d789dSPierre van Houtryve if (!Comps.empty()) { 85fa3d789dSPierre van Houtryve if (Comps.size() != 2) 86fa3d789dSPierre van Houtryve PrintFatalError(TheDef->getLoc(), 87fa3d789dSPierre van Houtryve "ComposedOf must have exactly two entries"); 88fa3d789dSPierre van Houtryve CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]); 89fa3d789dSPierre van Houtryve CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]); 90baf66ec0SCraig Topper CodeGenSubRegIndex *X = A->addComposite(B, this, RegBank.getHwModes()); 91fa3d789dSPierre van Houtryve if (X) 92fa3d789dSPierre van Houtryve PrintFatalError(TheDef->getLoc(), "Ambiguous ComposedOf entries"); 93fa3d789dSPierre van Houtryve } 94fa3d789dSPierre van Houtryve 953138eb50SRahul Joshi std::vector<const Record *> Parts = 96a140931bSRahul Joshi TheDef->getValueAsListOfDefs("CoveringSubRegIndices"); 97fa3d789dSPierre van Houtryve if (!Parts.empty()) { 98fa3d789dSPierre van Houtryve if (Parts.size() < 2) 99fa3d789dSPierre van Houtryve PrintFatalError(TheDef->getLoc(), 100fa3d789dSPierre van Houtryve "CoveredBySubRegs must have two or more entries"); 101fa3d789dSPierre van Houtryve SmallVector<CodeGenSubRegIndex *, 8> IdxParts; 1027c6592f5SRahul Joshi for (const Record *Part : Parts) 103fa3d789dSPierre van Houtryve IdxParts.push_back(RegBank.getSubRegIdx(Part)); 104fa3d789dSPierre van Houtryve setConcatenationOf(IdxParts); 105fa3d789dSPierre van Houtryve } 106fa3d789dSPierre van Houtryve } 107fa3d789dSPierre van Houtryve 108fa3d789dSPierre van Houtryve LaneBitmask CodeGenSubRegIndex::computeLaneMask() const { 109fa3d789dSPierre van Houtryve // Already computed? 110fa3d789dSPierre van Houtryve if (LaneMask.any()) 111fa3d789dSPierre van Houtryve return LaneMask; 112fa3d789dSPierre van Houtryve 113fa3d789dSPierre van Houtryve // Recursion guard, shouldn't be required. 114fa3d789dSPierre van Houtryve LaneMask = LaneBitmask::getAll(); 115fa3d789dSPierre van Houtryve 116fa3d789dSPierre van Houtryve // The lane mask is simply the union of all sub-indices. 117fa3d789dSPierre van Houtryve LaneBitmask M; 118fa3d789dSPierre van Houtryve for (const auto &C : Composed) 119fa3d789dSPierre van Houtryve M |= C.second->computeLaneMask(); 120fa3d789dSPierre van Houtryve assert(M.any() && "Missing lane mask, sub-register cycle?"); 121fa3d789dSPierre van Houtryve LaneMask = M; 122fa3d789dSPierre van Houtryve return LaneMask; 123fa3d789dSPierre van Houtryve } 124fa3d789dSPierre van Houtryve 125fa3d789dSPierre van Houtryve void CodeGenSubRegIndex::setConcatenationOf( 126fa3d789dSPierre van Houtryve ArrayRef<CodeGenSubRegIndex *> Parts) { 127fa3d789dSPierre van Houtryve if (ConcatenationOf.empty()) 128fa3d789dSPierre van Houtryve ConcatenationOf.assign(Parts.begin(), Parts.end()); 129fa3d789dSPierre van Houtryve else 130fa3d789dSPierre van Houtryve assert(std::equal(Parts.begin(), Parts.end(), ConcatenationOf.begin()) && 131fa3d789dSPierre van Houtryve "parts consistent"); 132fa3d789dSPierre van Houtryve } 133fa3d789dSPierre van Houtryve 134fa3d789dSPierre van Houtryve void CodeGenSubRegIndex::computeConcatTransitiveClosure() { 135fa3d789dSPierre van Houtryve for (SmallVectorImpl<CodeGenSubRegIndex *>::iterator I = 136fa3d789dSPierre van Houtryve ConcatenationOf.begin(); 137fa3d789dSPierre van Houtryve I != ConcatenationOf.end(); 138fa3d789dSPierre van Houtryve /*empty*/) { 139fa3d789dSPierre van Houtryve CodeGenSubRegIndex *SubIdx = *I; 140fa3d789dSPierre van Houtryve SubIdx->computeConcatTransitiveClosure(); 141fa3d789dSPierre van Houtryve #ifndef NDEBUG 142fa3d789dSPierre van Houtryve for (CodeGenSubRegIndex *SRI : SubIdx->ConcatenationOf) 143fa3d789dSPierre van Houtryve assert(SRI->ConcatenationOf.empty() && "No transitive closure?"); 144fa3d789dSPierre van Houtryve #endif 145fa3d789dSPierre van Houtryve 146fa3d789dSPierre van Houtryve if (SubIdx->ConcatenationOf.empty()) { 147fa3d789dSPierre van Houtryve ++I; 148fa3d789dSPierre van Houtryve } else { 149fa3d789dSPierre van Houtryve I = ConcatenationOf.erase(I); 150fa3d789dSPierre van Houtryve I = ConcatenationOf.insert(I, SubIdx->ConcatenationOf.begin(), 151fa3d789dSPierre van Houtryve SubIdx->ConcatenationOf.end()); 152fa3d789dSPierre van Houtryve I += SubIdx->ConcatenationOf.size(); 153fa3d789dSPierre van Houtryve } 154fa3d789dSPierre van Houtryve } 155fa3d789dSPierre van Houtryve } 156fa3d789dSPierre van Houtryve 157fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 158fa3d789dSPierre van Houtryve // CodeGenRegister 159fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 160fa3d789dSPierre van Houtryve 16116510149SRahul Joshi CodeGenRegister::CodeGenRegister(const Record *R, unsigned Enum) 162fa3d789dSPierre van Houtryve : TheDef(R), EnumValue(Enum), 163fa3d789dSPierre van Houtryve CostPerUse(R->getValueAsListOfInts("CostPerUse")), 164fa3d789dSPierre van Houtryve CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")), 165fa3d789dSPierre van Houtryve HasDisjunctSubRegs(false), Constant(R->getValueAsBit("isConstant")), 166fa3d789dSPierre van Houtryve SubRegsComplete(false), SuperRegsComplete(false), TopoSig(~0u) { 167fa3d789dSPierre van Houtryve Artificial = R->getValueAsBit("isArtificial"); 168fa3d789dSPierre van Houtryve } 169fa3d789dSPierre van Houtryve 170fa3d789dSPierre van Houtryve void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) { 1713138eb50SRahul Joshi std::vector<const Record *> SRIs = 172a140931bSRahul Joshi TheDef->getValueAsListOfDefs("SubRegIndices"); 173a140931bSRahul Joshi std::vector<const Record *> SRs = TheDef->getValueAsListOfDefs("SubRegs"); 174fa3d789dSPierre van Houtryve 175fa3d789dSPierre van Houtryve if (SRIs.size() != SRs.size()) 176fa3d789dSPierre van Houtryve PrintFatalError(TheDef->getLoc(), 177fa3d789dSPierre van Houtryve "SubRegs and SubRegIndices must have the same size"); 178fa3d789dSPierre van Houtryve 179fa3d789dSPierre van Houtryve for (unsigned i = 0, e = SRIs.size(); i != e; ++i) { 180fa3d789dSPierre van Houtryve ExplicitSubRegIndices.push_back(RegBank.getSubRegIdx(SRIs[i])); 181fa3d789dSPierre van Houtryve ExplicitSubRegs.push_back(RegBank.getReg(SRs[i])); 182fa3d789dSPierre van Houtryve } 183fa3d789dSPierre van Houtryve 184fa3d789dSPierre van Houtryve // Also compute leading super-registers. Each register has a list of 185fa3d789dSPierre van Houtryve // covered-by-subregs super-registers where it appears as the first explicit 186fa3d789dSPierre van Houtryve // sub-register. 187fa3d789dSPierre van Houtryve // 188fa3d789dSPierre van Houtryve // This is used by computeSecondarySubRegs() to find candidates. 189fa3d789dSPierre van Houtryve if (CoveredBySubRegs && !ExplicitSubRegs.empty()) 190fa3d789dSPierre van Houtryve ExplicitSubRegs.front()->LeadingSuperRegs.push_back(this); 191fa3d789dSPierre van Houtryve 192fa3d789dSPierre van Houtryve // Add ad hoc alias links. This is a symmetric relationship between two 193fa3d789dSPierre van Houtryve // registers, so build a symmetric graph by adding links in both ends. 1947c6592f5SRahul Joshi for (const Record *Alias : TheDef->getValueAsListOfDefs("Aliases")) { 195fa3d789dSPierre van Houtryve CodeGenRegister *Reg = RegBank.getReg(Alias); 196fa3d789dSPierre van Houtryve ExplicitAliases.push_back(Reg); 197fa3d789dSPierre van Houtryve Reg->ExplicitAliases.push_back(this); 198fa3d789dSPierre van Houtryve } 199fa3d789dSPierre van Houtryve } 200fa3d789dSPierre van Houtryve 201fa3d789dSPierre van Houtryve StringRef CodeGenRegister::getName() const { 202fa3d789dSPierre van Houtryve assert(TheDef && "no def"); 203fa3d789dSPierre van Houtryve return TheDef->getName(); 204fa3d789dSPierre van Houtryve } 205fa3d789dSPierre van Houtryve 206fa3d789dSPierre van Houtryve namespace { 207fa3d789dSPierre van Houtryve 208fa3d789dSPierre van Houtryve // Iterate over all register units in a set of registers. 209fa3d789dSPierre van Houtryve class RegUnitIterator { 210fa3d789dSPierre van Houtryve CodeGenRegister::Vec::const_iterator RegI, RegE; 211fa3d789dSPierre van Houtryve CodeGenRegister::RegUnitList::iterator UnitI, UnitE; 212fa3d789dSPierre van Houtryve static CodeGenRegister::RegUnitList Sentinel; 213fa3d789dSPierre van Houtryve 214fa3d789dSPierre van Houtryve public: 215fa3d789dSPierre van Houtryve RegUnitIterator(const CodeGenRegister::Vec &Regs) 216fa3d789dSPierre van Houtryve : RegI(Regs.begin()), RegE(Regs.end()) { 217fa3d789dSPierre van Houtryve 218fa3d789dSPierre van Houtryve if (RegI == RegE) { 219fa3d789dSPierre van Houtryve UnitI = Sentinel.end(); 220fa3d789dSPierre van Houtryve UnitE = Sentinel.end(); 221fa3d789dSPierre van Houtryve } else { 222fa3d789dSPierre van Houtryve UnitI = (*RegI)->getRegUnits().begin(); 223fa3d789dSPierre van Houtryve UnitE = (*RegI)->getRegUnits().end(); 224fa3d789dSPierre van Houtryve advance(); 225fa3d789dSPierre van Houtryve } 226fa3d789dSPierre van Houtryve } 227fa3d789dSPierre van Houtryve 228fa3d789dSPierre van Houtryve bool isValid() const { return UnitI != UnitE; } 229fa3d789dSPierre van Houtryve 230fa3d789dSPierre van Houtryve unsigned operator*() const { 231fa3d789dSPierre van Houtryve assert(isValid()); 232fa3d789dSPierre van Houtryve return *UnitI; 233fa3d789dSPierre van Houtryve } 234fa3d789dSPierre van Houtryve 235fa3d789dSPierre van Houtryve const CodeGenRegister *getReg() const { 236fa3d789dSPierre van Houtryve assert(isValid()); 237fa3d789dSPierre van Houtryve return *RegI; 238fa3d789dSPierre van Houtryve } 239fa3d789dSPierre van Houtryve 240fa3d789dSPierre van Houtryve /// Preincrement. Move to the next unit. 241fa3d789dSPierre van Houtryve void operator++() { 242fa3d789dSPierre van Houtryve assert(isValid() && "Cannot advance beyond the last operand"); 243fa3d789dSPierre van Houtryve ++UnitI; 244fa3d789dSPierre van Houtryve advance(); 245fa3d789dSPierre van Houtryve } 246fa3d789dSPierre van Houtryve 247fa3d789dSPierre van Houtryve protected: 248fa3d789dSPierre van Houtryve void advance() { 249fa3d789dSPierre van Houtryve while (UnitI == UnitE) { 250fa3d789dSPierre van Houtryve if (++RegI == RegE) 251fa3d789dSPierre van Houtryve break; 252fa3d789dSPierre van Houtryve UnitI = (*RegI)->getRegUnits().begin(); 253fa3d789dSPierre van Houtryve UnitE = (*RegI)->getRegUnits().end(); 254fa3d789dSPierre van Houtryve } 255fa3d789dSPierre van Houtryve } 256fa3d789dSPierre van Houtryve }; 257fa3d789dSPierre van Houtryve 258fa3d789dSPierre van Houtryve CodeGenRegister::RegUnitList RegUnitIterator::Sentinel; 259fa3d789dSPierre van Houtryve 260fa3d789dSPierre van Houtryve } // end anonymous namespace 261fa3d789dSPierre van Houtryve 262fa3d789dSPierre van Houtryve // Inherit register units from subregisters. 263fa3d789dSPierre van Houtryve // Return true if the RegUnits changed. 264fa3d789dSPierre van Houtryve bool CodeGenRegister::inheritRegUnits(CodeGenRegBank &RegBank) { 265fa3d789dSPierre van Houtryve bool changed = false; 266fa3d789dSPierre van Houtryve for (const auto &SubReg : SubRegs) { 267fa3d789dSPierre van Houtryve CodeGenRegister *SR = SubReg.second; 268fa3d789dSPierre van Houtryve // Merge the subregister's units into this register's RegUnits. 269fa3d789dSPierre van Houtryve changed |= (RegUnits |= SR->RegUnits); 270fa3d789dSPierre van Houtryve } 271fa3d789dSPierre van Houtryve 272fa3d789dSPierre van Houtryve return changed; 273fa3d789dSPierre van Houtryve } 274fa3d789dSPierre van Houtryve 275fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap & 276fa3d789dSPierre van Houtryve CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) { 277fa3d789dSPierre van Houtryve // Only compute this map once. 278fa3d789dSPierre van Houtryve if (SubRegsComplete) 279fa3d789dSPierre van Houtryve return SubRegs; 280fa3d789dSPierre van Houtryve SubRegsComplete = true; 281fa3d789dSPierre van Houtryve 282fa3d789dSPierre van Houtryve HasDisjunctSubRegs = ExplicitSubRegs.size() > 1; 283fa3d789dSPierre van Houtryve 284fa3d789dSPierre van Houtryve // First insert the explicit subregs and make sure they are fully indexed. 285fa3d789dSPierre van Houtryve for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) { 286fa3d789dSPierre van Houtryve CodeGenRegister *SR = ExplicitSubRegs[i]; 287fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Idx = ExplicitSubRegIndices[i]; 288fa3d789dSPierre van Houtryve if (!SR->Artificial) 289fa3d789dSPierre van Houtryve Idx->Artificial = false; 290*4e8c9d28SJay Foad if (!SubRegs.try_emplace(Idx, SR).second) 291fa3d789dSPierre van Houtryve PrintFatalError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() + 292fa3d789dSPierre van Houtryve " appears twice in Register " + 293fa3d789dSPierre van Houtryve getName()); 294fa3d789dSPierre van Houtryve // Map explicit sub-registers first, so the names take precedence. 295fa3d789dSPierre van Houtryve // The inherited sub-registers are mapped below. 296*4e8c9d28SJay Foad SubReg2Idx.try_emplace(SR, Idx); 297fa3d789dSPierre van Houtryve } 298fa3d789dSPierre van Houtryve 299fa3d789dSPierre van Houtryve // Keep track of inherited subregs and how they can be reached. 300fa3d789dSPierre van Houtryve SmallPtrSet<CodeGenRegister *, 8> Orphans; 301fa3d789dSPierre van Houtryve 302fa3d789dSPierre van Houtryve // Clone inherited subregs and place duplicate entries in Orphans. 303fa3d789dSPierre van Houtryve // Here the order is important - earlier subregs take precedence. 304fa3d789dSPierre van Houtryve for (CodeGenRegister *ESR : ExplicitSubRegs) { 305fa3d789dSPierre van Houtryve const SubRegMap &Map = ESR->computeSubRegs(RegBank); 306fa3d789dSPierre van Houtryve HasDisjunctSubRegs |= ESR->HasDisjunctSubRegs; 307fa3d789dSPierre van Houtryve 308fa3d789dSPierre van Houtryve for (const auto &SR : Map) { 309fa3d789dSPierre van Houtryve if (!SubRegs.insert(SR).second) 310fa3d789dSPierre van Houtryve Orphans.insert(SR.second); 311fa3d789dSPierre van Houtryve } 312fa3d789dSPierre van Houtryve } 313fa3d789dSPierre van Houtryve 314fa3d789dSPierre van Houtryve // Expand any composed subreg indices. 315fa3d789dSPierre van Houtryve // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a 316fa3d789dSPierre van Houtryve // qsub_1 subreg, add a dsub_2 subreg. Keep growing Indices and process 317fa3d789dSPierre van Houtryve // expanded subreg indices recursively. 318fa3d789dSPierre van Houtryve SmallVector<CodeGenSubRegIndex *, 8> Indices = ExplicitSubRegIndices; 319fa3d789dSPierre van Houtryve for (unsigned i = 0; i != Indices.size(); ++i) { 320fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Idx = Indices[i]; 321fa3d789dSPierre van Houtryve const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites(); 322fa3d789dSPierre van Houtryve CodeGenRegister *SR = SubRegs[Idx]; 323fa3d789dSPierre van Houtryve const SubRegMap &Map = SR->computeSubRegs(RegBank); 324fa3d789dSPierre van Houtryve 325fa3d789dSPierre van Houtryve // Look at the possible compositions of Idx. 326fa3d789dSPierre van Houtryve // They may not all be supported by SR. 327fa3d789dSPierre van Houtryve for (auto Comp : Comps) { 328fa3d789dSPierre van Houtryve SubRegMap::const_iterator SRI = Map.find(Comp.first); 329fa3d789dSPierre van Houtryve if (SRI == Map.end()) 330fa3d789dSPierre van Houtryve continue; // Idx + I->first doesn't exist in SR. 331fa3d789dSPierre van Houtryve // Add I->second as a name for the subreg SRI->second, assuming it is 332fa3d789dSPierre van Houtryve // orphaned, and the name isn't already used for something else. 333fa3d789dSPierre van Houtryve if (SubRegs.count(Comp.second) || !Orphans.erase(SRI->second)) 334fa3d789dSPierre van Houtryve continue; 335fa3d789dSPierre van Houtryve // We found a new name for the orphaned sub-register. 336*4e8c9d28SJay Foad SubRegs.try_emplace(Comp.second, SRI->second); 337fa3d789dSPierre van Houtryve Indices.push_back(Comp.second); 338fa3d789dSPierre van Houtryve } 339fa3d789dSPierre van Houtryve } 340fa3d789dSPierre van Houtryve 341fa3d789dSPierre van Houtryve // Now Orphans contains the inherited subregisters without a direct index. 342fa3d789dSPierre van Houtryve // Create inferred indexes for all missing entries. 343fa3d789dSPierre van Houtryve // Work backwards in the Indices vector in order to compose subregs bottom-up. 344fa3d789dSPierre van Houtryve // Consider this subreg sequence: 345fa3d789dSPierre van Houtryve // 346fa3d789dSPierre van Houtryve // qsub_1 -> dsub_0 -> ssub_0 347fa3d789dSPierre van Houtryve // 348fa3d789dSPierre van Houtryve // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register 349fa3d789dSPierre van Houtryve // can be reached in two different ways: 350fa3d789dSPierre van Houtryve // 351fa3d789dSPierre van Houtryve // qsub_1 -> ssub_0 352fa3d789dSPierre van Houtryve // dsub_2 -> ssub_0 353fa3d789dSPierre van Houtryve // 354fa3d789dSPierre van Houtryve // We pick the latter composition because another register may have [dsub_0, 355fa3d789dSPierre van Houtryve // dsub_1, dsub_2] subregs without necessarily having a qsub_1 subreg. The 356fa3d789dSPierre van Houtryve // dsub_2 -> ssub_0 composition can be shared. 357fa3d789dSPierre van Houtryve while (!Indices.empty() && !Orphans.empty()) { 358fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Idx = Indices.pop_back_val(); 359fa3d789dSPierre van Houtryve CodeGenRegister *SR = SubRegs[Idx]; 360fa3d789dSPierre van Houtryve const SubRegMap &Map = SR->computeSubRegs(RegBank); 361fa3d789dSPierre van Houtryve for (const auto &SubReg : Map) 362fa3d789dSPierre van Houtryve if (Orphans.erase(SubReg.second)) 363fa3d789dSPierre van Houtryve SubRegs[RegBank.getCompositeSubRegIndex(Idx, SubReg.first)] = 364fa3d789dSPierre van Houtryve SubReg.second; 365fa3d789dSPierre van Houtryve } 366fa3d789dSPierre van Houtryve 367fa3d789dSPierre van Houtryve // Compute the inverse SubReg -> Idx map. 368fa3d789dSPierre van Houtryve for (const auto &SubReg : SubRegs) { 369fa3d789dSPierre van Houtryve if (SubReg.second == this) { 370fa3d789dSPierre van Houtryve ArrayRef<SMLoc> Loc; 371fa3d789dSPierre van Houtryve if (TheDef) 372fa3d789dSPierre van Houtryve Loc = TheDef->getLoc(); 373fa3d789dSPierre van Houtryve PrintFatalError(Loc, "Register " + getName() + 374fa3d789dSPierre van Houtryve " has itself as a sub-register"); 375fa3d789dSPierre van Houtryve } 376fa3d789dSPierre van Houtryve 377fa3d789dSPierre van Houtryve // Compute AllSuperRegsCovered. 378fa3d789dSPierre van Houtryve if (!CoveredBySubRegs) 379fa3d789dSPierre van Houtryve SubReg.first->AllSuperRegsCovered = false; 380fa3d789dSPierre van Houtryve 381fa3d789dSPierre van Houtryve // Ensure that every sub-register has a unique name. 382fa3d789dSPierre van Houtryve DenseMap<const CodeGenRegister *, CodeGenSubRegIndex *>::iterator Ins = 383*4e8c9d28SJay Foad SubReg2Idx.try_emplace(SubReg.second, SubReg.first).first; 384fa3d789dSPierre van Houtryve if (Ins->second == SubReg.first) 385fa3d789dSPierre van Houtryve continue; 386fa3d789dSPierre van Houtryve // Trouble: Two different names for SubReg.second. 387fa3d789dSPierre van Houtryve ArrayRef<SMLoc> Loc; 388fa3d789dSPierre van Houtryve if (TheDef) 389fa3d789dSPierre van Houtryve Loc = TheDef->getLoc(); 390fa3d789dSPierre van Houtryve PrintFatalError( 391fa3d789dSPierre van Houtryve Loc, "Sub-register can't have two names: " + SubReg.second->getName() + 392fa3d789dSPierre van Houtryve " available as " + SubReg.first->getName() + " and " + 393fa3d789dSPierre van Houtryve Ins->second->getName()); 394fa3d789dSPierre van Houtryve } 395fa3d789dSPierre van Houtryve 396fa3d789dSPierre van Houtryve // Derive possible names for sub-register concatenations from any explicit 397fa3d789dSPierre van Houtryve // sub-registers. By doing this before computeSecondarySubRegs(), we ensure 398fa3d789dSPierre van Houtryve // that getConcatSubRegIndex() won't invent any concatenated indices that the 399fa3d789dSPierre van Houtryve // user already specified. 400fa3d789dSPierre van Houtryve for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) { 401fa3d789dSPierre van Houtryve CodeGenRegister *SR = ExplicitSubRegs[i]; 4029a211fe7SSander de Smalen if (!SR->CoveredBySubRegs || SR->Artificial) 403fa3d789dSPierre van Houtryve continue; 404fa3d789dSPierre van Houtryve 405fa3d789dSPierre van Houtryve // SR is composed of multiple sub-regs. Find their names in this register. 4069a211fe7SSander de Smalen bool AnyArtificial = false; 407fa3d789dSPierre van Houtryve SmallVector<CodeGenSubRegIndex *, 8> Parts; 408fa3d789dSPierre van Houtryve for (unsigned j = 0, e = SR->ExplicitSubRegs.size(); j != e; ++j) { 409fa3d789dSPierre van Houtryve CodeGenSubRegIndex &I = *SR->ExplicitSubRegIndices[j]; 4109a211fe7SSander de Smalen if (I.Artificial) { 4119a211fe7SSander de Smalen AnyArtificial = true; 4129a211fe7SSander de Smalen break; 4139a211fe7SSander de Smalen } 414fa3d789dSPierre van Houtryve Parts.push_back(getSubRegIndex(SR->ExplicitSubRegs[j])); 415fa3d789dSPierre van Houtryve } 416fa3d789dSPierre van Houtryve 4179a211fe7SSander de Smalen if (AnyArtificial) 4189a211fe7SSander de Smalen continue; 4199a211fe7SSander de Smalen 420fa3d789dSPierre van Houtryve // Offer this as an existing spelling for the concatenation of Parts. 421fa3d789dSPierre van Houtryve CodeGenSubRegIndex &Idx = *ExplicitSubRegIndices[i]; 422fa3d789dSPierre van Houtryve Idx.setConcatenationOf(Parts); 423fa3d789dSPierre van Houtryve } 424fa3d789dSPierre van Houtryve 425fa3d789dSPierre van Houtryve // Initialize RegUnitList. Because getSubRegs is called recursively, this 426fa3d789dSPierre van Houtryve // processes the register hierarchy in postorder. 427fa3d789dSPierre van Houtryve // 428fa3d789dSPierre van Houtryve // Inherit all sub-register units. It is good enough to look at the explicit 429fa3d789dSPierre van Houtryve // sub-registers, the other registers won't contribute any more units. 430fa3d789dSPierre van Houtryve for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) { 431fa3d789dSPierre van Houtryve CodeGenRegister *SR = ExplicitSubRegs[i]; 432fa3d789dSPierre van Houtryve RegUnits |= SR->RegUnits; 433fa3d789dSPierre van Houtryve } 434fa3d789dSPierre van Houtryve 435fa3d789dSPierre van Houtryve // Absent any ad hoc aliasing, we create one register unit per leaf register. 436fa3d789dSPierre van Houtryve // These units correspond to the maximal cliques in the register overlap 437fa3d789dSPierre van Houtryve // graph which is optimal. 438fa3d789dSPierre van Houtryve // 439fa3d789dSPierre van Houtryve // When there is ad hoc aliasing, we simply create one unit per edge in the 440fa3d789dSPierre van Houtryve // undirected ad hoc aliasing graph. Technically, we could do better by 441fa3d789dSPierre van Houtryve // identifying maximal cliques in the ad hoc graph, but cliques larger than 2 442fa3d789dSPierre van Houtryve // are extremely rare anyway (I've never seen one), so we don't bother with 443fa3d789dSPierre van Houtryve // the added complexity. 444fa3d789dSPierre van Houtryve for (unsigned i = 0, e = ExplicitAliases.size(); i != e; ++i) { 445fa3d789dSPierre van Houtryve CodeGenRegister *AR = ExplicitAliases[i]; 446fa3d789dSPierre van Houtryve // Only visit each edge once. 447fa3d789dSPierre van Houtryve if (AR->SubRegsComplete) 448fa3d789dSPierre van Houtryve continue; 449fa3d789dSPierre van Houtryve // Create a RegUnit representing this alias edge, and add it to both 450fa3d789dSPierre van Houtryve // registers. 451fa3d789dSPierre van Houtryve unsigned Unit = RegBank.newRegUnit(this, AR); 452fa3d789dSPierre van Houtryve RegUnits.set(Unit); 453fa3d789dSPierre van Houtryve AR->RegUnits.set(Unit); 454fa3d789dSPierre van Houtryve } 455fa3d789dSPierre van Houtryve 456fa3d789dSPierre van Houtryve // Finally, create units for leaf registers without ad hoc aliases. Note that 457fa3d789dSPierre van Houtryve // a leaf register with ad hoc aliases doesn't get its own unit - it isn't 458fa3d789dSPierre van Houtryve // necessary. This means the aliasing leaf registers can share a single unit. 459fa3d789dSPierre van Houtryve if (RegUnits.empty()) 460fa3d789dSPierre van Houtryve RegUnits.set(RegBank.newRegUnit(this)); 461fa3d789dSPierre van Houtryve 462fa3d789dSPierre van Houtryve // We have now computed the native register units. More may be adopted later 463fa3d789dSPierre van Houtryve // for balancing purposes. 464fa3d789dSPierre van Houtryve NativeRegUnits = RegUnits; 465fa3d789dSPierre van Houtryve 466fa3d789dSPierre van Houtryve return SubRegs; 467fa3d789dSPierre van Houtryve } 468fa3d789dSPierre van Houtryve 469fa3d789dSPierre van Houtryve // In a register that is covered by its sub-registers, try to find redundant 470fa3d789dSPierre van Houtryve // sub-registers. For example: 471fa3d789dSPierre van Houtryve // 472fa3d789dSPierre van Houtryve // QQ0 = {Q0, Q1} 473fa3d789dSPierre van Houtryve // Q0 = {D0, D1} 474fa3d789dSPierre van Houtryve // Q1 = {D2, D3} 475fa3d789dSPierre van Houtryve // 476fa3d789dSPierre van Houtryve // We can infer that D1_D2 is also a sub-register, even if it wasn't named in 477fa3d789dSPierre van Houtryve // the register definition. 478fa3d789dSPierre van Houtryve // 479fa3d789dSPierre van Houtryve // The explicitly specified registers form a tree. This function discovers 480fa3d789dSPierre van Houtryve // sub-register relationships that would force a DAG. 481fa3d789dSPierre van Houtryve // 482fa3d789dSPierre van Houtryve void CodeGenRegister::computeSecondarySubRegs(CodeGenRegBank &RegBank) { 483fa3d789dSPierre van Houtryve SmallVector<SubRegMap::value_type, 8> NewSubRegs; 484fa3d789dSPierre van Houtryve 485fa3d789dSPierre van Houtryve std::queue<std::pair<CodeGenSubRegIndex *, CodeGenRegister *>> SubRegQueue; 486fa3d789dSPierre van Houtryve for (std::pair<CodeGenSubRegIndex *, CodeGenRegister *> P : SubRegs) 487fa3d789dSPierre van Houtryve SubRegQueue.push(P); 488fa3d789dSPierre van Houtryve 489fa3d789dSPierre van Houtryve // Look at the leading super-registers of each sub-register. Those are the 490fa3d789dSPierre van Houtryve // candidates for new sub-registers, assuming they are fully contained in 491fa3d789dSPierre van Houtryve // this register. 492fa3d789dSPierre van Houtryve while (!SubRegQueue.empty()) { 493fa3d789dSPierre van Houtryve CodeGenSubRegIndex *SubRegIdx; 494fa3d789dSPierre van Houtryve const CodeGenRegister *SubReg; 495fa3d789dSPierre van Houtryve std::tie(SubRegIdx, SubReg) = SubRegQueue.front(); 496fa3d789dSPierre van Houtryve SubRegQueue.pop(); 497fa3d789dSPierre van Houtryve 498fa3d789dSPierre van Houtryve const CodeGenRegister::SuperRegList &Leads = SubReg->LeadingSuperRegs; 499fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Leads.size(); i != e; ++i) { 500fa3d789dSPierre van Houtryve CodeGenRegister *Cand = const_cast<CodeGenRegister *>(Leads[i]); 501fa3d789dSPierre van Houtryve // Already got this sub-register? 502fa3d789dSPierre van Houtryve if (Cand == this || getSubRegIndex(Cand)) 503fa3d789dSPierre van Houtryve continue; 504fa3d789dSPierre van Houtryve // Check if each component of Cand is already a sub-register. 505fa3d789dSPierre van Houtryve assert(!Cand->ExplicitSubRegs.empty() && 506fa3d789dSPierre van Houtryve "Super-register has no sub-registers"); 507fa3d789dSPierre van Houtryve if (Cand->ExplicitSubRegs.size() == 1) 508fa3d789dSPierre van Houtryve continue; 509fa3d789dSPierre van Houtryve SmallVector<CodeGenSubRegIndex *, 8> Parts; 510fa3d789dSPierre van Houtryve // We know that the first component is (SubRegIdx,SubReg). However we 511fa3d789dSPierre van Houtryve // may still need to split it into smaller subregister parts. 512fa3d789dSPierre van Houtryve assert(Cand->ExplicitSubRegs[0] == SubReg && "LeadingSuperRegs correct"); 513fa3d789dSPierre van Houtryve assert(getSubRegIndex(SubReg) == SubRegIdx && "LeadingSuperRegs correct"); 514fa3d789dSPierre van Houtryve for (CodeGenRegister *SubReg : Cand->ExplicitSubRegs) { 515fa3d789dSPierre van Houtryve if (CodeGenSubRegIndex *SubRegIdx = getSubRegIndex(SubReg)) { 516fa3d789dSPierre van Houtryve if (SubRegIdx->ConcatenationOf.empty()) 517fa3d789dSPierre van Houtryve Parts.push_back(SubRegIdx); 518fa3d789dSPierre van Houtryve else 519fa3d789dSPierre van Houtryve append_range(Parts, SubRegIdx->ConcatenationOf); 520fa3d789dSPierre van Houtryve } else { 521fa3d789dSPierre van Houtryve // Sub-register doesn't exist. 522fa3d789dSPierre van Houtryve Parts.clear(); 523fa3d789dSPierre van Houtryve break; 524fa3d789dSPierre van Houtryve } 525fa3d789dSPierre van Houtryve } 526fa3d789dSPierre van Houtryve // There is nothing to do if some Cand sub-register is not part of this 527fa3d789dSPierre van Houtryve // register. 528fa3d789dSPierre van Houtryve if (Parts.empty()) 529fa3d789dSPierre van Houtryve continue; 530fa3d789dSPierre van Houtryve 531fa3d789dSPierre van Houtryve // Each part of Cand is a sub-register of this. Make the full Cand also 532fa3d789dSPierre van Houtryve // a sub-register with a concatenated sub-register index. 533baf66ec0SCraig Topper CodeGenSubRegIndex *Concat = 534baf66ec0SCraig Topper RegBank.getConcatSubRegIndex(Parts, RegBank.getHwModes()); 535*4e8c9d28SJay Foad std::pair<CodeGenSubRegIndex *, CodeGenRegister *> NewSubReg = {Concat, 536*4e8c9d28SJay Foad Cand}; 537fa3d789dSPierre van Houtryve 538fa3d789dSPierre van Houtryve if (!SubRegs.insert(NewSubReg).second) 539fa3d789dSPierre van Houtryve continue; 540fa3d789dSPierre van Houtryve 541fa3d789dSPierre van Houtryve // We inserted a new subregister. 542fa3d789dSPierre van Houtryve NewSubRegs.push_back(NewSubReg); 543fa3d789dSPierre van Houtryve SubRegQueue.push(NewSubReg); 544*4e8c9d28SJay Foad SubReg2Idx.try_emplace(Cand, Concat); 545fa3d789dSPierre van Houtryve } 546fa3d789dSPierre van Houtryve } 547fa3d789dSPierre van Houtryve 548fa3d789dSPierre van Houtryve // Create sub-register index composition maps for the synthesized indices. 549fa3d789dSPierre van Houtryve for (unsigned i = 0, e = NewSubRegs.size(); i != e; ++i) { 550fa3d789dSPierre van Houtryve CodeGenSubRegIndex *NewIdx = NewSubRegs[i].first; 551fa3d789dSPierre van Houtryve CodeGenRegister *NewSubReg = NewSubRegs[i].second; 552fa3d789dSPierre van Houtryve for (auto SubReg : NewSubReg->SubRegs) { 553fa3d789dSPierre van Houtryve CodeGenSubRegIndex *SubIdx = getSubRegIndex(SubReg.second); 554fa3d789dSPierre van Houtryve if (!SubIdx) 555fa3d789dSPierre van Houtryve PrintFatalError(TheDef->getLoc(), "No SubRegIndex for " + 556fa3d789dSPierre van Houtryve SubReg.second->getName() + 557fa3d789dSPierre van Houtryve " in " + getName()); 558baf66ec0SCraig Topper NewIdx->addComposite(SubReg.first, SubIdx, RegBank.getHwModes()); 559fa3d789dSPierre van Houtryve } 560fa3d789dSPierre van Houtryve } 561fa3d789dSPierre van Houtryve } 562fa3d789dSPierre van Houtryve 563fa3d789dSPierre van Houtryve void CodeGenRegister::computeSuperRegs(CodeGenRegBank &RegBank) { 564fa3d789dSPierre van Houtryve // Only visit each register once. 565fa3d789dSPierre van Houtryve if (SuperRegsComplete) 566fa3d789dSPierre van Houtryve return; 567fa3d789dSPierre van Houtryve SuperRegsComplete = true; 568fa3d789dSPierre van Houtryve 569fa3d789dSPierre van Houtryve // Make sure all sub-registers have been visited first, so the super-reg 570fa3d789dSPierre van Houtryve // lists will be topologically ordered. 571fa3d789dSPierre van Houtryve for (auto SubReg : SubRegs) 572fa3d789dSPierre van Houtryve SubReg.second->computeSuperRegs(RegBank); 573fa3d789dSPierre van Houtryve 574fa3d789dSPierre van Houtryve // Now add this as a super-register on all sub-registers. 575fa3d789dSPierre van Houtryve // Also compute the TopoSigId in post-order. 576fa3d789dSPierre van Houtryve TopoSigId Id; 577fa3d789dSPierre van Houtryve for (auto SubReg : SubRegs) { 578fa3d789dSPierre van Houtryve // Topological signature computed from SubIdx, TopoId(SubReg). 579fa3d789dSPierre van Houtryve // Loops and idempotent indices have TopoSig = ~0u. 580fa3d789dSPierre van Houtryve Id.push_back(SubReg.first->EnumValue); 581fa3d789dSPierre van Houtryve Id.push_back(SubReg.second->TopoSig); 582fa3d789dSPierre van Houtryve 583fa3d789dSPierre van Houtryve // Don't add duplicate entries. 584fa3d789dSPierre van Houtryve if (!SubReg.second->SuperRegs.empty() && 585fa3d789dSPierre van Houtryve SubReg.second->SuperRegs.back() == this) 586fa3d789dSPierre van Houtryve continue; 587fa3d789dSPierre van Houtryve SubReg.second->SuperRegs.push_back(this); 588fa3d789dSPierre van Houtryve } 589fa3d789dSPierre van Houtryve TopoSig = RegBank.getTopoSig(Id); 590fa3d789dSPierre van Houtryve } 591fa3d789dSPierre van Houtryve 592fa3d789dSPierre van Houtryve void CodeGenRegister::addSubRegsPreOrder( 593fa3d789dSPierre van Houtryve SetVector<const CodeGenRegister *> &OSet, CodeGenRegBank &RegBank) const { 594fa3d789dSPierre van Houtryve assert(SubRegsComplete && "Must precompute sub-registers"); 595fa3d789dSPierre van Houtryve for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) { 596fa3d789dSPierre van Houtryve CodeGenRegister *SR = ExplicitSubRegs[i]; 597fa3d789dSPierre van Houtryve if (OSet.insert(SR)) 598fa3d789dSPierre van Houtryve SR->addSubRegsPreOrder(OSet, RegBank); 599fa3d789dSPierre van Houtryve } 600fa3d789dSPierre van Houtryve // Add any secondary sub-registers that weren't part of the explicit tree. 601fa3d789dSPierre van Houtryve for (auto SubReg : SubRegs) 602fa3d789dSPierre van Houtryve OSet.insert(SubReg.second); 603fa3d789dSPierre van Houtryve } 604fa3d789dSPierre van Houtryve 605fa3d789dSPierre van Houtryve // Get the sum of this register's unit weights. 606fa3d789dSPierre van Houtryve unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const { 607fa3d789dSPierre van Houtryve unsigned Weight = 0; 608fa3d789dSPierre van Houtryve for (unsigned RegUnit : RegUnits) { 609fa3d789dSPierre van Houtryve Weight += RegBank.getRegUnit(RegUnit).Weight; 610fa3d789dSPierre van Houtryve } 611fa3d789dSPierre van Houtryve return Weight; 612fa3d789dSPierre van Houtryve } 613fa3d789dSPierre van Houtryve 614fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 615fa3d789dSPierre van Houtryve // RegisterTuples 616fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 617fa3d789dSPierre van Houtryve 618fa3d789dSPierre van Houtryve // A RegisterTuples def is used to generate pseudo-registers from lists of 619fa3d789dSPierre van Houtryve // sub-registers. We provide a SetTheory expander class that returns the new 620fa3d789dSPierre van Houtryve // registers. 621fa3d789dSPierre van Houtryve namespace { 622fa3d789dSPierre van Houtryve 623fa3d789dSPierre van Houtryve struct TupleExpander : SetTheory::Expander { 624fa3d789dSPierre van Houtryve // Reference to SynthDefs in the containing CodeGenRegBank, to keep track of 625fa3d789dSPierre van Houtryve // the synthesized definitions for their lifetime. 626fa3d789dSPierre van Houtryve std::vector<std::unique_ptr<Record>> &SynthDefs; 627fa3d789dSPierre van Houtryve 628edf5782fSJason Eckhardt // Track all synthesized tuple names in order to detect duplicate definitions. 629edf5782fSJason Eckhardt llvm::StringSet<> TupleNames; 630edf5782fSJason Eckhardt 631fa3d789dSPierre van Houtryve TupleExpander(std::vector<std::unique_ptr<Record>> &SynthDefs) 632fa3d789dSPierre van Houtryve : SynthDefs(SynthDefs) {} 633fa3d789dSPierre van Houtryve 634d7da79f2SRahul Joshi void expand(SetTheory &ST, const Record *Def, 635d7da79f2SRahul Joshi SetTheory::RecSet &Elts) override { 6363138eb50SRahul Joshi std::vector<const Record *> Indices = 637a140931bSRahul Joshi Def->getValueAsListOfDefs("SubRegIndices"); 638fa3d789dSPierre van Houtryve unsigned Dim = Indices.size(); 63962e2c7fbSRahul Joshi const ListInit *SubRegs = Def->getValueAsListInit("SubRegs"); 640fa3d789dSPierre van Houtryve if (Dim != SubRegs->size()) 641fa3d789dSPierre van Houtryve PrintFatalError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch"); 642fa3d789dSPierre van Houtryve if (Dim < 2) 643fa3d789dSPierre van Houtryve PrintFatalError(Def->getLoc(), 644fa3d789dSPierre van Houtryve "Tuples must have at least 2 sub-registers"); 645fa3d789dSPierre van Houtryve 646fa3d789dSPierre van Houtryve // Evaluate the sub-register lists to be zipped. 647fa3d789dSPierre van Houtryve unsigned Length = ~0u; 648fa3d789dSPierre van Houtryve SmallVector<SetTheory::RecSet, 4> Lists(Dim); 649fa3d789dSPierre van Houtryve for (unsigned i = 0; i != Dim; ++i) { 650fa3d789dSPierre van Houtryve ST.evaluate(SubRegs->getElement(i), Lists[i], Def->getLoc()); 651fa3d789dSPierre van Houtryve Length = std::min(Length, unsigned(Lists[i].size())); 652fa3d789dSPierre van Houtryve } 653fa3d789dSPierre van Houtryve 654fa3d789dSPierre van Houtryve if (Length == 0) 655fa3d789dSPierre van Houtryve return; 656fa3d789dSPierre van Houtryve 657fa3d789dSPierre van Houtryve // Precompute some types. 658743f839aSRahul Joshi const Record *RegisterCl = Def->getRecords().getClass("Register"); 6599d95e261SRahul Joshi const RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl); 660fa3d789dSPierre van Houtryve std::vector<StringRef> RegNames = 661fa3d789dSPierre van Houtryve Def->getValueAsListOfStrings("RegAsmNames"); 662fa3d789dSPierre van Houtryve 663fa3d789dSPierre van Houtryve // Zip them up. 664fa3d789dSPierre van Houtryve RecordKeeper &RK = Def->getRecords(); 665fa3d789dSPierre van Houtryve for (unsigned n = 0; n != Length; ++n) { 666fa3d789dSPierre van Houtryve std::string Name; 66716510149SRahul Joshi const Record *Proto = Lists[0][n]; 668fa3d789dSPierre van Houtryve std::vector<Init *> Tuple; 669fa3d789dSPierre van Houtryve for (unsigned i = 0; i != Dim; ++i) { 67016510149SRahul Joshi const Record *Reg = Lists[i][n]; 671fa3d789dSPierre van Houtryve if (i) 672fa3d789dSPierre van Houtryve Name += '_'; 673fa3d789dSPierre van Houtryve Name += Reg->getName(); 674ce3c58e1SRahul Joshi Tuple.push_back(Reg->getDefInit()); 675fa3d789dSPierre van Houtryve } 676fa3d789dSPierre van Houtryve 677fa3d789dSPierre van Houtryve // Take the cost list of the first register in the tuple. 67862e2c7fbSRahul Joshi const ListInit *CostList = Proto->getValueAsListInit("CostPerUse"); 67962e2c7fbSRahul Joshi SmallVector<const Init *, 2> CostPerUse; 680fa3d789dSPierre van Houtryve CostPerUse.insert(CostPerUse.end(), CostList->begin(), CostList->end()); 681fa3d789dSPierre van Houtryve 68262e2c7fbSRahul Joshi const StringInit *AsmName = StringInit::get(RK, ""); 683fa3d789dSPierre van Houtryve if (!RegNames.empty()) { 684fa3d789dSPierre van Houtryve if (RegNames.size() <= n) 685fa3d789dSPierre van Houtryve PrintFatalError(Def->getLoc(), 686fa3d789dSPierre van Houtryve "Register tuple definition missing name for '" + 687fa3d789dSPierre van Houtryve Name + "'."); 688fa3d789dSPierre van Houtryve AsmName = StringInit::get(RK, RegNames[n]); 689fa3d789dSPierre van Houtryve } 690fa3d789dSPierre van Houtryve 691fa3d789dSPierre van Houtryve // Create a new Record representing the synthesized register. This record 692fa3d789dSPierre van Houtryve // is only for consumption by CodeGenRegister, it is not added to the 693fa3d789dSPierre van Houtryve // RecordKeeper. 694fa3d789dSPierre van Houtryve SynthDefs.emplace_back( 695fa3d789dSPierre van Houtryve std::make_unique<Record>(Name, Def->getLoc(), Def->getRecords())); 696fa3d789dSPierre van Houtryve Record *NewReg = SynthDefs.back().get(); 697fa3d789dSPierre van Houtryve Elts.insert(NewReg); 698fa3d789dSPierre van Houtryve 699edf5782fSJason Eckhardt // Detect duplicates among synthesized registers. 700edf5782fSJason Eckhardt const auto Res = TupleNames.insert(NewReg->getName()); 701edf5782fSJason Eckhardt if (!Res.second) 702edf5782fSJason Eckhardt PrintFatalError(Def->getLoc(), 703edf5782fSJason Eckhardt "Register tuple redefines register '" + Name + "'."); 704edf5782fSJason Eckhardt 705fa3d789dSPierre van Houtryve // Copy Proto super-classes. 70665e69f74SRahul Joshi for (const auto &[Super, Loc] : Proto->getSuperClasses()) 70765e69f74SRahul Joshi NewReg->addSuperClass(Super, Loc); 708fa3d789dSPierre van Houtryve 709fa3d789dSPierre van Houtryve // Copy Proto fields. 710fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) { 711fa3d789dSPierre van Houtryve RecordVal RV = Proto->getValues()[i]; 712fa3d789dSPierre van Houtryve 713fa3d789dSPierre van Houtryve // Skip existing fields, like NAME. 714fa3d789dSPierre van Houtryve if (NewReg->getValue(RV.getNameInit())) 715fa3d789dSPierre van Houtryve continue; 716fa3d789dSPierre van Houtryve 717fa3d789dSPierre van Houtryve StringRef Field = RV.getName(); 718fa3d789dSPierre van Houtryve 719fa3d789dSPierre van Houtryve // Replace the sub-register list with Tuple. 720fa3d789dSPierre van Houtryve if (Field == "SubRegs") 721fa3d789dSPierre van Houtryve RV.setValue(ListInit::get(Tuple, RegisterRecTy)); 722fa3d789dSPierre van Houtryve 723fa3d789dSPierre van Houtryve if (Field == "AsmName") 724fa3d789dSPierre van Houtryve RV.setValue(AsmName); 725fa3d789dSPierre van Houtryve 726fa3d789dSPierre van Houtryve // CostPerUse is aggregated from all Tuple members. 727fa3d789dSPierre van Houtryve if (Field == "CostPerUse") 728fa3d789dSPierre van Houtryve RV.setValue(ListInit::get(CostPerUse, CostList->getElementType())); 729fa3d789dSPierre van Houtryve 730fa3d789dSPierre van Houtryve // Composite registers are always covered by sub-registers. 731fa3d789dSPierre van Houtryve if (Field == "CoveredBySubRegs") 732fa3d789dSPierre van Houtryve RV.setValue(BitInit::get(RK, true)); 733fa3d789dSPierre van Houtryve 734fa3d789dSPierre van Houtryve // Copy fields from the RegisterTuples def. 735fa3d789dSPierre van Houtryve if (Field == "SubRegIndices" || Field == "CompositeIndices") { 736fa3d789dSPierre van Houtryve NewReg->addValue(*Def->getValue(Field)); 737fa3d789dSPierre van Houtryve continue; 738fa3d789dSPierre van Houtryve } 739fa3d789dSPierre van Houtryve 740fa3d789dSPierre van Houtryve // Some fields get their default uninitialized value. 741fa3d789dSPierre van Houtryve if (Field == "DwarfNumbers" || Field == "DwarfAlias" || 742fa3d789dSPierre van Houtryve Field == "Aliases") { 743fa3d789dSPierre van Houtryve if (const RecordVal *DefRV = RegisterCl->getValue(Field)) 744fa3d789dSPierre van Houtryve NewReg->addValue(*DefRV); 745fa3d789dSPierre van Houtryve continue; 746fa3d789dSPierre van Houtryve } 747fa3d789dSPierre van Houtryve 748fa3d789dSPierre van Houtryve // Everything else is copied from Proto. 749fa3d789dSPierre van Houtryve NewReg->addValue(RV); 750fa3d789dSPierre van Houtryve } 751fa3d789dSPierre van Houtryve } 752fa3d789dSPierre van Houtryve } 753fa3d789dSPierre van Houtryve }; 754fa3d789dSPierre van Houtryve 755fa3d789dSPierre van Houtryve } // end anonymous namespace 756fa3d789dSPierre van Houtryve 757fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 758fa3d789dSPierre van Houtryve // CodeGenRegisterClass 759fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 760fa3d789dSPierre van Houtryve 761fa3d789dSPierre van Houtryve static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) { 762fa3d789dSPierre van Houtryve llvm::sort(M, deref<std::less<>>()); 763d9293519SKazu Hirata M.erase(llvm::unique(M, deref<std::equal_to<>>()), M.end()); 764fa3d789dSPierre van Houtryve } 765fa3d789dSPierre van Houtryve 7667c6592f5SRahul Joshi CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, 7677c6592f5SRahul Joshi const Record *R) 768fa3d789dSPierre van Houtryve : TheDef(R), Name(std::string(R->getName())), 769fa3d789dSPierre van Houtryve TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), TSFlags(0) { 770fa3d789dSPierre van Houtryve GeneratePressureSet = R->getValueAsBit("GeneratePressureSet"); 771a140931bSRahul Joshi std::vector<const Record *> TypeList = R->getValueAsListOfDefs("RegTypes"); 772fa3d789dSPierre van Houtryve if (TypeList.empty()) 773fa3d789dSPierre van Houtryve PrintFatalError(R->getLoc(), "RegTypes list must not be empty!"); 774fa3d789dSPierre van Houtryve for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { 7757c6592f5SRahul Joshi const Record *Type = TypeList[i]; 776fa3d789dSPierre van Houtryve if (!Type->isSubClassOf("ValueType")) 777fa3d789dSPierre van Houtryve PrintFatalError(R->getLoc(), 778fa3d789dSPierre van Houtryve "RegTypes list member '" + Type->getName() + 779fa3d789dSPierre van Houtryve "' does not derive from the ValueType class!"); 780fa3d789dSPierre van Houtryve VTs.push_back(getValueTypeByHwMode(Type, RegBank.getHwModes())); 781fa3d789dSPierre van Houtryve } 782fa3d789dSPierre van Houtryve 783fa3d789dSPierre van Houtryve // Allocation order 0 is the full set. AltOrders provides others. 784fa3d789dSPierre van Houtryve const SetTheory::RecVec *Elements = RegBank.getSets().expand(R); 78562e2c7fbSRahul Joshi const ListInit *AltOrders = R->getValueAsListInit("AltOrders"); 786fa3d789dSPierre van Houtryve Orders.resize(1 + AltOrders->size()); 787fa3d789dSPierre van Houtryve 788fa3d789dSPierre van Houtryve // Default allocation order always contains all registers. 789fa3d789dSPierre van Houtryve Artificial = true; 790fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Elements->size(); i != e; ++i) { 791fa3d789dSPierre van Houtryve Orders[0].push_back((*Elements)[i]); 792fa3d789dSPierre van Houtryve const CodeGenRegister *Reg = RegBank.getReg((*Elements)[i]); 793fa3d789dSPierre van Houtryve Members.push_back(Reg); 794fa3d789dSPierre van Houtryve Artificial &= Reg->Artificial; 795fa3d789dSPierre van Houtryve TopoSigs.set(Reg->getTopoSig()); 796fa3d789dSPierre van Houtryve } 797fa3d789dSPierre van Houtryve sortAndUniqueRegisters(Members); 798fa3d789dSPierre van Houtryve 799fa3d789dSPierre van Houtryve // Alternative allocation orders may be subsets. 800fa3d789dSPierre van Houtryve SetTheory::RecSet Order; 801fa3d789dSPierre van Houtryve for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) { 802fa3d789dSPierre van Houtryve RegBank.getSets().evaluate(AltOrders->getElement(i), Order, R->getLoc()); 803fa3d789dSPierre van Houtryve Orders[1 + i].append(Order.begin(), Order.end()); 804fa3d789dSPierre van Houtryve // Verify that all altorder members are regclass members. 805fa3d789dSPierre van Houtryve while (!Order.empty()) { 806fa3d789dSPierre van Houtryve CodeGenRegister *Reg = RegBank.getReg(Order.back()); 807fa3d789dSPierre van Houtryve Order.pop_back(); 808fa3d789dSPierre van Houtryve if (!contains(Reg)) 809fa3d789dSPierre van Houtryve PrintFatalError(R->getLoc(), " AltOrder register " + Reg->getName() + 810fa3d789dSPierre van Houtryve " is not a class member"); 811fa3d789dSPierre van Houtryve } 812fa3d789dSPierre van Houtryve } 813fa3d789dSPierre van Houtryve 814fa3d789dSPierre van Houtryve Namespace = R->getValueAsString("Namespace"); 815fa3d789dSPierre van Houtryve 816fa3d789dSPierre van Houtryve if (const RecordVal *RV = R->getValue("RegInfos")) 81762e2c7fbSRahul Joshi if (const DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) 818fa3d789dSPierre van Houtryve RSI = RegSizeInfoByHwMode(DI->getDef(), RegBank.getHwModes()); 819fa3d789dSPierre van Houtryve unsigned Size = R->getValueAsInt("Size"); 820fa3d789dSPierre van Houtryve assert((RSI.hasDefault() || Size != 0 || VTs[0].isSimple()) && 821fa3d789dSPierre van Houtryve "Impossible to determine register size"); 822fa3d789dSPierre van Houtryve if (!RSI.hasDefault()) { 823fa3d789dSPierre van Houtryve RegSizeInfo RI; 824fa3d789dSPierre van Houtryve RI.RegSize = RI.SpillSize = 825fa3d789dSPierre van Houtryve Size ? Size : VTs[0].getSimple().getSizeInBits(); 826fa3d789dSPierre van Houtryve RI.SpillAlignment = R->getValueAsInt("Alignment"); 827fa3d789dSPierre van Houtryve RSI.insertRegSizeForMode(DefaultMode, RI); 828fa3d789dSPierre van Houtryve } 829fa3d789dSPierre van Houtryve 830fa3d789dSPierre van Houtryve CopyCost = R->getValueAsInt("CopyCost"); 831fa3d789dSPierre van Houtryve Allocatable = R->getValueAsBit("isAllocatable"); 832fa3d789dSPierre van Houtryve AltOrderSelect = R->getValueAsString("AltOrderSelect"); 833fa3d789dSPierre van Houtryve int AllocationPriority = R->getValueAsInt("AllocationPriority"); 834fa3d789dSPierre van Houtryve if (!isUInt<5>(AllocationPriority)) 835fa3d789dSPierre van Houtryve PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,31]"); 836fa3d789dSPierre van Houtryve this->AllocationPriority = AllocationPriority; 837fa3d789dSPierre van Houtryve 838fa3d789dSPierre van Houtryve GlobalPriority = R->getValueAsBit("GlobalPriority"); 839fa3d789dSPierre van Houtryve 84062e2c7fbSRahul Joshi const BitsInit *TSF = R->getValueAsBitsInit("TSFlags"); 841fa3d789dSPierre van Houtryve for (unsigned I = 0, E = TSF->getNumBits(); I != E; ++I) { 84262e2c7fbSRahul Joshi const BitInit *Bit = cast<BitInit>(TSF->getBit(I)); 843fa3d789dSPierre van Houtryve TSFlags |= uint8_t(Bit->getValue()) << I; 844fa3d789dSPierre van Houtryve } 845fa3d789dSPierre van Houtryve } 846fa3d789dSPierre van Houtryve 847fa3d789dSPierre van Houtryve // Create an inferred register class that was missing from the .td files. 848fa3d789dSPierre van Houtryve // Most properties will be inherited from the closest super-class after the 849fa3d789dSPierre van Houtryve // class structure has been computed. 850fa3d789dSPierre van Houtryve CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, 851fa3d789dSPierre van Houtryve StringRef Name, Key Props) 852fa3d789dSPierre van Houtryve : Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)), 853fa3d789dSPierre van Houtryve TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI), 854fa3d789dSPierre van Houtryve CopyCost(0), Allocatable(true), AllocationPriority(0), 855fa3d789dSPierre van Houtryve GlobalPriority(false), TSFlags(0) { 856fa3d789dSPierre van Houtryve Artificial = true; 857fa3d789dSPierre van Houtryve GeneratePressureSet = false; 858fa3d789dSPierre van Houtryve for (const auto R : Members) { 859fa3d789dSPierre van Houtryve TopoSigs.set(R->getTopoSig()); 860fa3d789dSPierre van Houtryve Artificial &= R->Artificial; 861fa3d789dSPierre van Houtryve } 862fa3d789dSPierre van Houtryve } 863fa3d789dSPierre van Houtryve 864fa3d789dSPierre van Houtryve // Compute inherited propertied for a synthesized register class. 865fa3d789dSPierre van Houtryve void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) { 866fa3d789dSPierre van Houtryve assert(!getDef() && "Only synthesized classes can inherit properties"); 867fa3d789dSPierre van Houtryve assert(!SuperClasses.empty() && "Synthesized class without super class"); 868fa3d789dSPierre van Houtryve 869fa3d789dSPierre van Houtryve // The last super-class is the smallest one. 870fa3d789dSPierre van Houtryve CodeGenRegisterClass &Super = *SuperClasses.back(); 871fa3d789dSPierre van Houtryve 872fa3d789dSPierre van Houtryve // Most properties are copied directly. 873fa3d789dSPierre van Houtryve // Exceptions are members, size, and alignment 874fa3d789dSPierre van Houtryve Namespace = Super.Namespace; 875fa3d789dSPierre van Houtryve VTs = Super.VTs; 876fa3d789dSPierre van Houtryve CopyCost = Super.CopyCost; 877fa3d789dSPierre van Houtryve // Check for allocatable superclasses. 878fa3d789dSPierre van Houtryve Allocatable = any_of(SuperClasses, [&](const CodeGenRegisterClass *S) { 879fa3d789dSPierre van Houtryve return S->Allocatable; 880fa3d789dSPierre van Houtryve }); 881fa3d789dSPierre van Houtryve AltOrderSelect = Super.AltOrderSelect; 882fa3d789dSPierre van Houtryve AllocationPriority = Super.AllocationPriority; 883fa3d789dSPierre van Houtryve GlobalPriority = Super.GlobalPriority; 884fa3d789dSPierre van Houtryve TSFlags = Super.TSFlags; 885fa3d789dSPierre van Houtryve GeneratePressureSet |= Super.GeneratePressureSet; 886fa3d789dSPierre van Houtryve 887fa3d789dSPierre van Houtryve // Copy all allocation orders, filter out foreign registers from the larger 888fa3d789dSPierre van Houtryve // super-class. 889fa3d789dSPierre van Houtryve Orders.resize(Super.Orders.size()); 890fa3d789dSPierre van Houtryve for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i) 891fa3d789dSPierre van Houtryve for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j) 892fa3d789dSPierre van Houtryve if (contains(RegBank.getReg(Super.Orders[i][j]))) 893fa3d789dSPierre van Houtryve Orders[i].push_back(Super.Orders[i][j]); 894fa3d789dSPierre van Houtryve } 895fa3d789dSPierre van Houtryve 896fa3d789dSPierre van Houtryve bool CodeGenRegisterClass::hasType(const ValueTypeByHwMode &VT) const { 897fa3d789dSPierre van Houtryve if (llvm::is_contained(VTs, VT)) 898fa3d789dSPierre van Houtryve return true; 899fa3d789dSPierre van Houtryve 900fa3d789dSPierre van Houtryve // If VT is not identical to any of this class's types, but is a simple 901fa3d789dSPierre van Houtryve // type, check if any of the types for this class contain it under some 902fa3d789dSPierre van Houtryve // mode. 903fa3d789dSPierre van Houtryve // The motivating example came from RISC-V, where (likely because of being 904fa3d789dSPierre van Houtryve // guarded by "64-bit" predicate), the type of X5 was {*:[i64]}, but the 905fa3d789dSPierre van Houtryve // type in GRC was {*:[i32], m1:[i64]}. 906fa3d789dSPierre van Houtryve if (VT.isSimple()) { 907fa3d789dSPierre van Houtryve MVT T = VT.getSimple(); 908fa3d789dSPierre van Houtryve for (const ValueTypeByHwMode &OurVT : VTs) { 909fa3d789dSPierre van Houtryve if (llvm::count_if(OurVT, [T](auto &&P) { return P.second == T; })) 910fa3d789dSPierre van Houtryve return true; 911fa3d789dSPierre van Houtryve } 912fa3d789dSPierre van Houtryve } 913fa3d789dSPierre van Houtryve return false; 914fa3d789dSPierre van Houtryve } 915fa3d789dSPierre van Houtryve 916fa3d789dSPierre van Houtryve bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { 917fa3d789dSPierre van Houtryve return std::binary_search(Members.begin(), Members.end(), Reg, 918fa3d789dSPierre van Houtryve deref<std::less<>>()); 919fa3d789dSPierre van Houtryve } 920fa3d789dSPierre van Houtryve 921fa3d789dSPierre van Houtryve unsigned CodeGenRegisterClass::getWeight(const CodeGenRegBank &RegBank) const { 922fa3d789dSPierre van Houtryve if (TheDef && !TheDef->isValueUnset("Weight")) 923fa3d789dSPierre van Houtryve return TheDef->getValueAsInt("Weight"); 924fa3d789dSPierre van Houtryve 925fa3d789dSPierre van Houtryve if (Members.empty() || Artificial) 926fa3d789dSPierre van Houtryve return 0; 927fa3d789dSPierre van Houtryve 928fa3d789dSPierre van Houtryve return (*Members.begin())->getWeight(RegBank); 929fa3d789dSPierre van Houtryve } 930fa3d789dSPierre van Houtryve 931fa3d789dSPierre van Houtryve namespace llvm { 932fa3d789dSPierre van Houtryve 933fa3d789dSPierre van Houtryve raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) { 934fa3d789dSPierre van Houtryve OS << "{ " << K.RSI; 935fa3d789dSPierre van Houtryve for (const auto R : *K.Members) 936fa3d789dSPierre van Houtryve OS << ", " << R->getName(); 937fa3d789dSPierre van Houtryve return OS << " }"; 938fa3d789dSPierre van Houtryve } 939fa3d789dSPierre van Houtryve 940fa3d789dSPierre van Houtryve } // end namespace llvm 941fa3d789dSPierre van Houtryve 942fa3d789dSPierre van Houtryve // This is a simple lexicographical order that can be used to search for sets. 943fa3d789dSPierre van Houtryve // It is not the same as the topological order provided by TopoOrderRC. 944fa3d789dSPierre van Houtryve bool CodeGenRegisterClass::Key::operator<( 945fa3d789dSPierre van Houtryve const CodeGenRegisterClass::Key &B) const { 946fa3d789dSPierre van Houtryve assert(Members && B.Members); 947fa3d789dSPierre van Houtryve return std::tie(*Members, RSI) < std::tie(*B.Members, B.RSI); 948fa3d789dSPierre van Houtryve } 949fa3d789dSPierre van Houtryve 950fa3d789dSPierre van Houtryve // Returns true if RC is a strict subclass. 951fa3d789dSPierre van Houtryve // RC is a sub-class of this class if it is a valid replacement for any 952fa3d789dSPierre van Houtryve // instruction operand where a register of this classis required. It must 953fa3d789dSPierre van Houtryve // satisfy these conditions: 954fa3d789dSPierre van Houtryve // 955fa3d789dSPierre van Houtryve // 1. All RC registers are also in this. 956fa3d789dSPierre van Houtryve // 2. The RC spill size must not be smaller than our spill size. 957fa3d789dSPierre van Houtryve // 3. RC spill alignment must be compatible with ours. 958fa3d789dSPierre van Houtryve // 959fa3d789dSPierre van Houtryve static bool testSubClass(const CodeGenRegisterClass *A, 960fa3d789dSPierre van Houtryve const CodeGenRegisterClass *B) { 961fa3d789dSPierre van Houtryve return A->RSI.isSubClassOf(B->RSI) && 962fa3d789dSPierre van Houtryve std::includes(A->getMembers().begin(), A->getMembers().end(), 963fa3d789dSPierre van Houtryve B->getMembers().begin(), B->getMembers().end(), 964fa3d789dSPierre van Houtryve deref<std::less<>>()); 965fa3d789dSPierre van Houtryve } 966fa3d789dSPierre van Houtryve 967fa3d789dSPierre van Houtryve /// Sorting predicate for register classes. This provides a topological 968fa3d789dSPierre van Houtryve /// ordering that arranges all register classes before their sub-classes. 969fa3d789dSPierre van Houtryve /// 970fa3d789dSPierre van Houtryve /// Register classes with the same registers, spill size, and alignment form a 971fa3d789dSPierre van Houtryve /// clique. They will be ordered alphabetically. 972fa3d789dSPierre van Houtryve /// 973fa3d789dSPierre van Houtryve static bool TopoOrderRC(const CodeGenRegisterClass &PA, 974fa3d789dSPierre van Houtryve const CodeGenRegisterClass &PB) { 975fa3d789dSPierre van Houtryve auto *A = &PA; 976fa3d789dSPierre van Houtryve auto *B = &PB; 977fa3d789dSPierre van Houtryve if (A == B) 978fa3d789dSPierre van Houtryve return false; 979fa3d789dSPierre van Houtryve 980fa3d789dSPierre van Houtryve if (A->RSI < B->RSI) 981fa3d789dSPierre van Houtryve return true; 982fa3d789dSPierre van Houtryve if (A->RSI != B->RSI) 983fa3d789dSPierre van Houtryve return false; 984fa3d789dSPierre van Houtryve 985fa3d789dSPierre van Houtryve // Order by descending set size. Note that the classes' allocation order may 986fa3d789dSPierre van Houtryve // not have been computed yet. The Members set is always vaild. 987fa3d789dSPierre van Houtryve if (A->getMembers().size() > B->getMembers().size()) 988fa3d789dSPierre van Houtryve return true; 989fa3d789dSPierre van Houtryve if (A->getMembers().size() < B->getMembers().size()) 990fa3d789dSPierre van Houtryve return false; 991fa3d789dSPierre van Houtryve 992fa3d789dSPierre van Houtryve // Finally order by name as a tie breaker. 993fa3d789dSPierre van Houtryve return StringRef(A->getName()) < B->getName(); 994fa3d789dSPierre van Houtryve } 995fa3d789dSPierre van Houtryve 996fa3d789dSPierre van Houtryve std::string CodeGenRegisterClass::getNamespaceQualification() const { 997fa3d789dSPierre van Houtryve return Namespace.empty() ? "" : (Namespace + "::").str(); 998fa3d789dSPierre van Houtryve } 999fa3d789dSPierre van Houtryve 1000fa3d789dSPierre van Houtryve std::string CodeGenRegisterClass::getQualifiedName() const { 1001fa3d789dSPierre van Houtryve return getNamespaceQualification() + getName(); 1002fa3d789dSPierre van Houtryve } 1003fa3d789dSPierre van Houtryve 1004fa3d789dSPierre van Houtryve std::string CodeGenRegisterClass::getIdName() const { 1005fa3d789dSPierre van Houtryve return getName() + "RegClassID"; 1006fa3d789dSPierre van Houtryve } 1007fa3d789dSPierre van Houtryve 1008fa3d789dSPierre van Houtryve std::string CodeGenRegisterClass::getQualifiedIdName() const { 1009fa3d789dSPierre van Houtryve return getNamespaceQualification() + getIdName(); 1010fa3d789dSPierre van Houtryve } 1011fa3d789dSPierre van Houtryve 1012fa3d789dSPierre van Houtryve // Compute sub-classes of all register classes. 1013fa3d789dSPierre van Houtryve // Assume the classes are ordered topologically. 1014fa3d789dSPierre van Houtryve void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) { 1015fa3d789dSPierre van Houtryve auto &RegClasses = RegBank.getRegClasses(); 1016fa3d789dSPierre van Houtryve 1017fa3d789dSPierre van Houtryve // Visit backwards so sub-classes are seen first. 1018fa3d789dSPierre van Houtryve for (auto I = RegClasses.rbegin(), E = RegClasses.rend(); I != E; ++I) { 1019fa3d789dSPierre van Houtryve CodeGenRegisterClass &RC = *I; 1020fa3d789dSPierre van Houtryve RC.SubClasses.resize(RegClasses.size()); 1021fa3d789dSPierre van Houtryve RC.SubClasses.set(RC.EnumValue); 1022fa3d789dSPierre van Houtryve if (RC.Artificial) 1023fa3d789dSPierre van Houtryve continue; 1024fa3d789dSPierre van Houtryve 1025fa3d789dSPierre van Houtryve // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. 1026fa3d789dSPierre van Houtryve for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) { 1027fa3d789dSPierre van Houtryve CodeGenRegisterClass &SubRC = *I2; 1028fa3d789dSPierre van Houtryve if (RC.SubClasses.test(SubRC.EnumValue)) 1029fa3d789dSPierre van Houtryve continue; 1030fa3d789dSPierre van Houtryve if (!testSubClass(&RC, &SubRC)) 1031fa3d789dSPierre van Houtryve continue; 1032fa3d789dSPierre van Houtryve // SubRC is a sub-class. Grap all its sub-classes so we won't have to 1033fa3d789dSPierre van Houtryve // check them again. 1034fa3d789dSPierre van Houtryve RC.SubClasses |= SubRC.SubClasses; 1035fa3d789dSPierre van Houtryve } 1036fa3d789dSPierre van Houtryve 1037fa3d789dSPierre van Houtryve // Sweep up missed clique members. They will be immediately preceding RC. 1038fa3d789dSPierre van Houtryve for (auto I2 = std::next(I); I2 != E && testSubClass(&RC, &*I2); ++I2) 1039fa3d789dSPierre van Houtryve RC.SubClasses.set(I2->EnumValue); 1040fa3d789dSPierre van Houtryve } 1041fa3d789dSPierre van Houtryve 1042fa3d789dSPierre van Houtryve // Compute the SuperClasses lists from the SubClasses vectors. 1043fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) { 1044fa3d789dSPierre van Houtryve const BitVector &SC = RC.getSubClasses(); 1045fa3d789dSPierre van Houtryve auto I = RegClasses.begin(); 1046fa3d789dSPierre van Houtryve for (int s = 0, next_s = SC.find_first(); next_s != -1; 1047fa3d789dSPierre van Houtryve next_s = SC.find_next(s)) { 1048fa3d789dSPierre van Houtryve std::advance(I, next_s - s); 1049fa3d789dSPierre van Houtryve s = next_s; 1050fa3d789dSPierre van Houtryve if (&*I == &RC) 1051fa3d789dSPierre van Houtryve continue; 1052fa3d789dSPierre van Houtryve I->SuperClasses.push_back(&RC); 1053fa3d789dSPierre van Houtryve } 1054fa3d789dSPierre van Houtryve } 1055fa3d789dSPierre van Houtryve 1056fa3d789dSPierre van Houtryve // With the class hierarchy in place, let synthesized register classes inherit 1057fa3d789dSPierre van Houtryve // properties from their closest super-class. The iteration order here can 1058fa3d789dSPierre van Houtryve // propagate properties down multiple levels. 1059fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) 1060fa3d789dSPierre van Houtryve if (!RC.getDef()) 1061fa3d789dSPierre van Houtryve RC.inheritProperties(RegBank); 1062fa3d789dSPierre van Houtryve } 1063fa3d789dSPierre van Houtryve 1064fa3d789dSPierre van Houtryve std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>> 1065fa3d789dSPierre van Houtryve CodeGenRegisterClass::getMatchingSubClassWithSubRegs( 1066fa3d789dSPierre van Houtryve CodeGenRegBank &RegBank, const CodeGenSubRegIndex *SubIdx) const { 1067fa3d789dSPierre van Houtryve auto WeakSizeOrder = [this](const CodeGenRegisterClass *A, 1068fa3d789dSPierre van Houtryve const CodeGenRegisterClass *B) { 1069fa3d789dSPierre van Houtryve // If there are multiple, identical register classes, prefer the original 1070fa3d789dSPierre van Houtryve // register class. 1071fa3d789dSPierre van Houtryve if (A == B) 1072fa3d789dSPierre van Houtryve return false; 1073fa3d789dSPierre van Houtryve if (A->getMembers().size() == B->getMembers().size()) 1074fa3d789dSPierre van Houtryve return A == this; 1075fa3d789dSPierre van Houtryve return A->getMembers().size() > B->getMembers().size(); 1076fa3d789dSPierre van Houtryve }; 1077fa3d789dSPierre van Houtryve 1078fa3d789dSPierre van Houtryve auto &RegClasses = RegBank.getRegClasses(); 1079fa3d789dSPierre van Houtryve 1080fa3d789dSPierre van Houtryve // Find all the subclasses of this one that fully support the sub-register 1081fa3d789dSPierre van Houtryve // index and order them by size. BiggestSuperRC should always be first. 1082fa3d789dSPierre van Houtryve CodeGenRegisterClass *BiggestSuperRegRC = getSubClassWithSubReg(SubIdx); 1083fa3d789dSPierre van Houtryve if (!BiggestSuperRegRC) 1084fa3d789dSPierre van Houtryve return std::nullopt; 1085fa3d789dSPierre van Houtryve BitVector SuperRegRCsBV = BiggestSuperRegRC->getSubClasses(); 1086fa3d789dSPierre van Houtryve std::vector<CodeGenRegisterClass *> SuperRegRCs; 1087fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) 1088fa3d789dSPierre van Houtryve if (SuperRegRCsBV[RC.EnumValue]) 1089fa3d789dSPierre van Houtryve SuperRegRCs.emplace_back(&RC); 1090fa3d789dSPierre van Houtryve llvm::stable_sort(SuperRegRCs, WeakSizeOrder); 1091fa3d789dSPierre van Houtryve 1092fa3d789dSPierre van Houtryve assert(SuperRegRCs.front() == BiggestSuperRegRC && 1093fa3d789dSPierre van Houtryve "Biggest class wasn't first"); 1094fa3d789dSPierre van Houtryve 1095fa3d789dSPierre van Houtryve // Find all the subreg classes and order them by size too. 1096fa3d789dSPierre van Houtryve std::vector<std::pair<CodeGenRegisterClass *, BitVector>> SuperRegClasses; 1097fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) { 1098fa3d789dSPierre van Houtryve BitVector SuperRegClassesBV(RegClasses.size()); 1099fa3d789dSPierre van Houtryve RC.getSuperRegClasses(SubIdx, SuperRegClassesBV); 1100fa3d789dSPierre van Houtryve if (SuperRegClassesBV.any()) 1101*4e8c9d28SJay Foad SuperRegClasses.emplace_back(&RC, SuperRegClassesBV); 1102fa3d789dSPierre van Houtryve } 1103fa3d789dSPierre van Houtryve llvm::stable_sort(SuperRegClasses, 1104fa3d789dSPierre van Houtryve [&](const std::pair<CodeGenRegisterClass *, BitVector> &A, 1105fa3d789dSPierre van Houtryve const std::pair<CodeGenRegisterClass *, BitVector> &B) { 1106fa3d789dSPierre van Houtryve return WeakSizeOrder(A.first, B.first); 1107fa3d789dSPierre van Houtryve }); 1108fa3d789dSPierre van Houtryve 1109fa3d789dSPierre van Houtryve // Find the biggest subclass and subreg class such that R:subidx is in the 1110fa3d789dSPierre van Houtryve // subreg class for all R in subclass. 1111fa3d789dSPierre van Houtryve // 1112fa3d789dSPierre van Houtryve // For example: 1113fa3d789dSPierre van Houtryve // All registers in X86's GR64 have a sub_32bit subregister but no class 1114fa3d789dSPierre van Houtryve // exists that contains all the 32-bit subregisters because GR64 contains RIP 1115fa3d789dSPierre van Houtryve // but GR32 does not contain EIP. Instead, we constrain SuperRegRC to 1116fa3d789dSPierre van Houtryve // GR32_with_sub_8bit (which is identical to GR32_with_sub_32bit) and then, 1117fa3d789dSPierre van Houtryve // having excluded RIP, we are able to find a SubRegRC (GR32). 1118fa3d789dSPierre van Houtryve CodeGenRegisterClass *ChosenSuperRegClass = nullptr; 1119fa3d789dSPierre van Houtryve CodeGenRegisterClass *SubRegRC = nullptr; 1120fa3d789dSPierre van Houtryve for (auto *SuperRegRC : SuperRegRCs) { 1121fa3d789dSPierre van Houtryve for (const auto &SuperRegClassPair : SuperRegClasses) { 1122fa3d789dSPierre van Houtryve const BitVector &SuperRegClassBV = SuperRegClassPair.second; 1123fa3d789dSPierre van Houtryve if (SuperRegClassBV[SuperRegRC->EnumValue]) { 1124fa3d789dSPierre van Houtryve SubRegRC = SuperRegClassPair.first; 1125fa3d789dSPierre van Houtryve ChosenSuperRegClass = SuperRegRC; 1126fa3d789dSPierre van Houtryve 1127fa3d789dSPierre van Houtryve // If SubRegRC is bigger than SuperRegRC then there are members of 1128fa3d789dSPierre van Houtryve // SubRegRC that don't have super registers via SubIdx. Keep looking to 1129fa3d789dSPierre van Houtryve // find a better fit and fall back on this one if there isn't one. 1130fa3d789dSPierre van Houtryve // 1131fa3d789dSPierre van Houtryve // This is intended to prevent X86 from making odd choices such as 1132fa3d789dSPierre van Houtryve // picking LOW32_ADDR_ACCESS_RBP instead of GR32 in the example above. 1133fa3d789dSPierre van Houtryve // LOW32_ADDR_ACCESS_RBP is a valid choice but contains registers that 1134fa3d789dSPierre van Houtryve // aren't subregisters of SuperRegRC whereas GR32 has a direct 1:1 1135fa3d789dSPierre van Houtryve // mapping. 1136fa3d789dSPierre van Houtryve if (SuperRegRC->getMembers().size() >= SubRegRC->getMembers().size()) 1137fa3d789dSPierre van Houtryve return std::pair(ChosenSuperRegClass, SubRegRC); 1138fa3d789dSPierre van Houtryve } 1139fa3d789dSPierre van Houtryve } 1140fa3d789dSPierre van Houtryve 1141fa3d789dSPierre van Houtryve // If we found a fit but it wasn't quite ideal because SubRegRC had excess 1142fa3d789dSPierre van Houtryve // registers, then we're done. 1143fa3d789dSPierre van Houtryve if (ChosenSuperRegClass) 1144fa3d789dSPierre van Houtryve return std::pair(ChosenSuperRegClass, SubRegRC); 1145fa3d789dSPierre van Houtryve } 1146fa3d789dSPierre van Houtryve 1147fa3d789dSPierre van Houtryve return std::nullopt; 1148fa3d789dSPierre van Houtryve } 1149fa3d789dSPierre van Houtryve 1150fa3d789dSPierre van Houtryve void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx, 1151fa3d789dSPierre van Houtryve BitVector &Out) const { 1152fa3d789dSPierre van Houtryve auto FindI = SuperRegClasses.find(SubIdx); 1153fa3d789dSPierre van Houtryve if (FindI == SuperRegClasses.end()) 1154fa3d789dSPierre van Houtryve return; 1155fa3d789dSPierre van Houtryve for (CodeGenRegisterClass *RC : FindI->second) 1156fa3d789dSPierre van Houtryve Out.set(RC->EnumValue); 1157fa3d789dSPierre van Houtryve } 1158fa3d789dSPierre van Houtryve 1159fa3d789dSPierre van Houtryve // Populate a unique sorted list of units from a register set. 1160fa3d789dSPierre van Houtryve void CodeGenRegisterClass::buildRegUnitSet( 1161fa3d789dSPierre van Houtryve const CodeGenRegBank &RegBank, std::vector<unsigned> &RegUnits) const { 1162fa3d789dSPierre van Houtryve std::vector<unsigned> TmpUnits; 1163fa3d789dSPierre van Houtryve for (RegUnitIterator UnitI(Members); UnitI.isValid(); ++UnitI) { 1164fa3d789dSPierre van Houtryve const RegUnit &RU = RegBank.getRegUnit(*UnitI); 1165fa3d789dSPierre van Houtryve if (!RU.Artificial) 1166fa3d789dSPierre van Houtryve TmpUnits.push_back(*UnitI); 1167fa3d789dSPierre van Houtryve } 1168fa3d789dSPierre van Houtryve llvm::sort(TmpUnits); 1169fa3d789dSPierre van Houtryve std::unique_copy(TmpUnits.begin(), TmpUnits.end(), 1170fa3d789dSPierre van Houtryve std::back_inserter(RegUnits)); 1171fa3d789dSPierre van Houtryve } 1172fa3d789dSPierre van Houtryve 1173fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 1174fa3d789dSPierre van Houtryve // CodeGenRegisterCategory 1175fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 1176fa3d789dSPierre van Houtryve 1177fa3d789dSPierre van Houtryve CodeGenRegisterCategory::CodeGenRegisterCategory(CodeGenRegBank &RegBank, 11787c6592f5SRahul Joshi const Record *R) 1179fa3d789dSPierre van Houtryve : TheDef(R), Name(std::string(R->getName())) { 11807c6592f5SRahul Joshi for (const Record *RegClass : R->getValueAsListOfDefs("Classes")) 1181fa3d789dSPierre van Houtryve Classes.push_back(RegBank.getRegClass(RegClass)); 1182fa3d789dSPierre van Houtryve } 1183fa3d789dSPierre van Houtryve 1184fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 1185fa3d789dSPierre van Houtryve // CodeGenRegBank 1186fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 1187fa3d789dSPierre van Houtryve 11887c6592f5SRahul Joshi CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records, 1189fa3d789dSPierre van Houtryve const CodeGenHwModes &Modes) 1190fa3d789dSPierre van Houtryve : CGH(Modes) { 1191fa3d789dSPierre van Houtryve // Configure register Sets to understand register classes and tuples. 1192fa3d789dSPierre van Houtryve Sets.addFieldExpander("RegisterClass", "MemberList"); 1193fa3d789dSPierre van Houtryve Sets.addFieldExpander("CalleeSavedRegs", "SaveList"); 1194fa3d789dSPierre van Houtryve Sets.addExpander("RegisterTuples", 1195fa3d789dSPierre van Houtryve std::make_unique<TupleExpander>(SynthDefs)); 1196fa3d789dSPierre van Houtryve 1197fa3d789dSPierre van Houtryve // Read in the user-defined (named) sub-register indices. 1198fa3d789dSPierre van Houtryve // More indices will be synthesized later. 11997c6592f5SRahul Joshi for (const Record *SRI : Records.getAllDerivedDefinitions("SubRegIndex")) 12007c6592f5SRahul Joshi getSubRegIdx(SRI); 1201fa3d789dSPierre van Houtryve // Build composite maps from ComposedOf fields. 1202fa3d789dSPierre van Houtryve for (auto &Idx : SubRegIndices) 1203fa3d789dSPierre van Houtryve Idx.updateComponents(*this); 1204fa3d789dSPierre van Houtryve 1205fa3d789dSPierre van Houtryve // Read in the register and register tuple definitions. 120616510149SRahul Joshi const RecordKeeper &RC = Records; 120716510149SRahul Joshi std::vector<const Record *> Regs = RC.getAllDerivedDefinitions("Register"); 1208fa3d789dSPierre van Houtryve if (!Regs.empty() && Regs[0]->isSubClassOf("X86Reg")) { 1209fa3d789dSPierre van Houtryve // For X86, we need to sort Registers and RegisterTuples together to list 1210fa3d789dSPierre van Houtryve // new registers and register tuples at a later position. So that we can 1211fa3d789dSPierre van Houtryve // reduce unnecessary iterations on unsupported registers in LiveVariables. 1212fa3d789dSPierre van Houtryve // TODO: Remove this logic when migrate from LiveVariables to LiveIntervals 1213fa3d789dSPierre van Houtryve // completely. 121416510149SRahul Joshi for (const Record *R : Records.getAllDerivedDefinitions("RegisterTuples")) { 1215fa3d789dSPierre van Houtryve // Expand tuples and merge the vectors 121616510149SRahul Joshi std::vector<const Record *> TupRegs = *Sets.expand(R); 1217fa3d789dSPierre van Houtryve Regs.insert(Regs.end(), TupRegs.begin(), TupRegs.end()); 1218fa3d789dSPierre van Houtryve } 1219fa3d789dSPierre van Houtryve 1220fa3d789dSPierre van Houtryve llvm::sort(Regs, LessRecordRegister()); 1221fa3d789dSPierre van Houtryve // Assign the enumeration values. 1222fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Regs.size(); i != e; ++i) 1223fa3d789dSPierre van Houtryve getReg(Regs[i]); 1224fa3d789dSPierre van Houtryve } else { 1225fa3d789dSPierre van Houtryve llvm::sort(Regs, LessRecordRegister()); 1226fa3d789dSPierre van Houtryve // Assign the enumeration values. 1227fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Regs.size(); i != e; ++i) 1228fa3d789dSPierre van Houtryve getReg(Regs[i]); 1229fa3d789dSPierre van Houtryve 1230fa3d789dSPierre van Houtryve // Expand tuples and number the new registers. 12317c6592f5SRahul Joshi for (const Record *R : Records.getAllDerivedDefinitions("RegisterTuples")) { 123216510149SRahul Joshi std::vector<const Record *> TupRegs = *Sets.expand(R); 1233fa3d789dSPierre van Houtryve llvm::sort(TupRegs, LessRecordRegister()); 123416510149SRahul Joshi for (const Record *RC : TupRegs) 1235fa3d789dSPierre van Houtryve getReg(RC); 1236fa3d789dSPierre van Houtryve } 1237fa3d789dSPierre van Houtryve } 1238fa3d789dSPierre van Houtryve 1239fa3d789dSPierre van Houtryve // Now all the registers are known. Build the object graph of explicit 1240fa3d789dSPierre van Houtryve // register-register references. 1241fa3d789dSPierre van Houtryve for (auto &Reg : Registers) 1242fa3d789dSPierre van Houtryve Reg.buildObjectGraph(*this); 1243fa3d789dSPierre van Houtryve 1244fa3d789dSPierre van Houtryve // Compute register name map. 1245fa3d789dSPierre van Houtryve for (auto &Reg : Registers) 1246fa3d789dSPierre van Houtryve // FIXME: This could just be RegistersByName[name] = register, except that 1247fa3d789dSPierre van Houtryve // causes some failures in MIPS - perhaps they have duplicate register name 1248fa3d789dSPierre van Houtryve // entries? (or maybe there's a reason for it - I don't know much about this 1249fa3d789dSPierre van Houtryve // code, just drive-by refactoring) 1250*4e8c9d28SJay Foad RegistersByName.try_emplace(Reg.TheDef->getValueAsString("AsmName"), &Reg); 1251fa3d789dSPierre van Houtryve 1252fa3d789dSPierre van Houtryve // Precompute all sub-register maps. 1253fa3d789dSPierre van Houtryve // This will create Composite entries for all inferred sub-register indices. 1254fa3d789dSPierre van Houtryve for (auto &Reg : Registers) 1255fa3d789dSPierre van Houtryve Reg.computeSubRegs(*this); 1256fa3d789dSPierre van Houtryve 1257fa3d789dSPierre van Houtryve // Compute transitive closure of subregister index ConcatenationOf vectors 1258fa3d789dSPierre van Houtryve // and initialize ConcatIdx map. 1259fa3d789dSPierre van Houtryve for (CodeGenSubRegIndex &SRI : SubRegIndices) { 1260fa3d789dSPierre van Houtryve SRI.computeConcatTransitiveClosure(); 1261fa3d789dSPierre van Houtryve if (!SRI.ConcatenationOf.empty()) 1262*4e8c9d28SJay Foad ConcatIdx.try_emplace( 1263*4e8c9d28SJay Foad SmallVector<CodeGenSubRegIndex *, 8>(SRI.ConcatenationOf.begin(), 1264*4e8c9d28SJay Foad SRI.ConcatenationOf.end()), 1265*4e8c9d28SJay Foad &SRI); 1266fa3d789dSPierre van Houtryve } 1267fa3d789dSPierre van Houtryve 1268fa3d789dSPierre van Houtryve // Infer even more sub-registers by combining leading super-registers. 1269fa3d789dSPierre van Houtryve for (auto &Reg : Registers) 1270fa3d789dSPierre van Houtryve if (Reg.CoveredBySubRegs) 1271fa3d789dSPierre van Houtryve Reg.computeSecondarySubRegs(*this); 1272fa3d789dSPierre van Houtryve 1273fa3d789dSPierre van Houtryve // After the sub-register graph is complete, compute the topologically 1274fa3d789dSPierre van Houtryve // ordered SuperRegs list. 1275fa3d789dSPierre van Houtryve for (auto &Reg : Registers) 1276fa3d789dSPierre van Houtryve Reg.computeSuperRegs(*this); 1277fa3d789dSPierre van Houtryve 1278fa3d789dSPierre van Houtryve // For each pair of Reg:SR, if both are non-artificial, mark the 1279fa3d789dSPierre van Houtryve // corresponding sub-register index as non-artificial. 1280fa3d789dSPierre van Houtryve for (auto &Reg : Registers) { 1281fa3d789dSPierre van Houtryve if (Reg.Artificial) 1282fa3d789dSPierre van Houtryve continue; 1283fa3d789dSPierre van Houtryve for (auto P : Reg.getSubRegs()) { 1284fa3d789dSPierre van Houtryve const CodeGenRegister *SR = P.second; 1285fa3d789dSPierre van Houtryve if (!SR->Artificial) 1286fa3d789dSPierre van Houtryve P.first->Artificial = false; 1287fa3d789dSPierre van Houtryve } 1288fa3d789dSPierre van Houtryve } 1289fa3d789dSPierre van Houtryve 1290fa3d789dSPierre van Houtryve // Native register units are associated with a leaf register. They've all been 1291fa3d789dSPierre van Houtryve // discovered now. 1292fa3d789dSPierre van Houtryve NumNativeRegUnits = RegUnits.size(); 1293fa3d789dSPierre van Houtryve 1294fa3d789dSPierre van Houtryve // Read in register class definitions. 12957c6592f5SRahul Joshi ArrayRef<const Record *> RCs = 12967c6592f5SRahul Joshi Records.getAllDerivedDefinitions("RegisterClass"); 1297fa3d789dSPierre van Houtryve if (RCs.empty()) 1298fa3d789dSPierre van Houtryve PrintFatalError("No 'RegisterClass' subclasses defined!"); 1299fa3d789dSPierre van Houtryve 1300fa3d789dSPierre van Houtryve // Allocate user-defined register classes. 1301fa3d789dSPierre van Houtryve for (auto *R : RCs) { 1302fa3d789dSPierre van Houtryve RegClasses.emplace_back(*this, R); 1303fa3d789dSPierre van Houtryve CodeGenRegisterClass &RC = RegClasses.back(); 1304fa3d789dSPierre van Houtryve if (!RC.Artificial) 1305fa3d789dSPierre van Houtryve addToMaps(&RC); 1306fa3d789dSPierre van Houtryve } 1307fa3d789dSPierre van Houtryve 1308fa3d789dSPierre van Houtryve // Infer missing classes to create a full algebra. 1309fa3d789dSPierre van Houtryve computeInferredRegisterClasses(); 1310fa3d789dSPierre van Houtryve 1311fa3d789dSPierre van Houtryve // Order register classes topologically and assign enum values. 1312fa3d789dSPierre van Houtryve RegClasses.sort(TopoOrderRC); 1313fa3d789dSPierre van Houtryve unsigned i = 0; 1314fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) 1315fa3d789dSPierre van Houtryve RC.EnumValue = i++; 1316fa3d789dSPierre van Houtryve CodeGenRegisterClass::computeSubClasses(*this); 1317fa3d789dSPierre van Houtryve 1318fa3d789dSPierre van Houtryve // Read in the register category definitions. 13197c6592f5SRahul Joshi for (const Record *R : Records.getAllDerivedDefinitions("RegisterCategory")) 1320fa3d789dSPierre van Houtryve RegCategories.emplace_back(*this, R); 1321fa3d789dSPierre van Houtryve } 1322fa3d789dSPierre van Houtryve 1323fa3d789dSPierre van Houtryve // Create a synthetic CodeGenSubRegIndex without a corresponding Record. 1324fa3d789dSPierre van Houtryve CodeGenSubRegIndex *CodeGenRegBank::createSubRegIndex(StringRef Name, 1325fa3d789dSPierre van Houtryve StringRef Namespace) { 1326fa3d789dSPierre van Houtryve SubRegIndices.emplace_back(Name, Namespace, SubRegIndices.size() + 1); 1327fa3d789dSPierre van Houtryve return &SubRegIndices.back(); 1328fa3d789dSPierre van Houtryve } 1329fa3d789dSPierre van Houtryve 13307c6592f5SRahul Joshi CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(const Record *Def) { 1331fa3d789dSPierre van Houtryve CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def]; 1332fa3d789dSPierre van Houtryve if (Idx) 1333fa3d789dSPierre van Houtryve return Idx; 1334baf66ec0SCraig Topper SubRegIndices.emplace_back(Def, SubRegIndices.size() + 1, getHwModes()); 1335fa3d789dSPierre van Houtryve Idx = &SubRegIndices.back(); 1336fa3d789dSPierre van Houtryve return Idx; 1337fa3d789dSPierre van Houtryve } 1338fa3d789dSPierre van Houtryve 1339fa3d789dSPierre van Houtryve const CodeGenSubRegIndex * 1340fa3d789dSPierre van Houtryve CodeGenRegBank::findSubRegIdx(const Record *Def) const { 1341fa3d789dSPierre van Houtryve return Def2SubRegIdx.lookup(Def); 1342fa3d789dSPierre van Houtryve } 1343fa3d789dSPierre van Houtryve 134416510149SRahul Joshi CodeGenRegister *CodeGenRegBank::getReg(const Record *Def) { 1345fa3d789dSPierre van Houtryve CodeGenRegister *&Reg = Def2Reg[Def]; 1346fa3d789dSPierre van Houtryve if (Reg) 1347fa3d789dSPierre van Houtryve return Reg; 1348fa3d789dSPierre van Houtryve Registers.emplace_back(Def, Registers.size() + 1); 1349fa3d789dSPierre van Houtryve Reg = &Registers.back(); 1350fa3d789dSPierre van Houtryve return Reg; 1351fa3d789dSPierre van Houtryve } 1352fa3d789dSPierre van Houtryve 1353fa3d789dSPierre van Houtryve void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) { 1354bdf02249SRahul Joshi if (const Record *Def = RC->getDef()) 1355*4e8c9d28SJay Foad Def2RC.try_emplace(Def, RC); 1356fa3d789dSPierre van Houtryve 1357fa3d789dSPierre van Houtryve // Duplicate classes are rejected by insert(). 1358fa3d789dSPierre van Houtryve // That's OK, we only care about the properties handled by CGRC::Key. 1359fa3d789dSPierre van Houtryve CodeGenRegisterClass::Key K(*RC); 1360*4e8c9d28SJay Foad Key2RC.try_emplace(K, RC); 1361fa3d789dSPierre van Houtryve } 1362fa3d789dSPierre van Houtryve 1363fa3d789dSPierre van Houtryve // Create a synthetic sub-class if it is missing. 1364fa3d789dSPierre van Houtryve CodeGenRegisterClass * 1365fa3d789dSPierre van Houtryve CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC, 1366fa3d789dSPierre van Houtryve const CodeGenRegister::Vec *Members, 1367fa3d789dSPierre van Houtryve StringRef Name) { 1368fa3d789dSPierre van Houtryve // Synthetic sub-class has the same size and alignment as RC. 1369fa3d789dSPierre van Houtryve CodeGenRegisterClass::Key K(Members, RC->RSI); 1370fa3d789dSPierre van Houtryve RCKeyMap::const_iterator FoundI = Key2RC.find(K); 1371fa3d789dSPierre van Houtryve if (FoundI != Key2RC.end()) 1372fa3d789dSPierre van Houtryve return FoundI->second; 1373fa3d789dSPierre van Houtryve 1374fa3d789dSPierre van Houtryve // Sub-class doesn't exist, create a new one. 1375fa3d789dSPierre van Houtryve RegClasses.emplace_back(*this, Name, K); 1376fa3d789dSPierre van Houtryve addToMaps(&RegClasses.back()); 1377fa3d789dSPierre van Houtryve return &RegClasses.back(); 1378fa3d789dSPierre van Houtryve } 1379fa3d789dSPierre van Houtryve 1380fa3d789dSPierre van Houtryve CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def) const { 1381fa3d789dSPierre van Houtryve if (CodeGenRegisterClass *RC = Def2RC.lookup(Def)) 1382fa3d789dSPierre van Houtryve return RC; 1383fa3d789dSPierre van Houtryve 1384fa3d789dSPierre van Houtryve PrintFatalError(Def->getLoc(), "Not a known RegisterClass!"); 1385fa3d789dSPierre van Houtryve } 1386fa3d789dSPierre van Houtryve 1387fa3d789dSPierre van Houtryve CodeGenSubRegIndex * 1388fa3d789dSPierre van Houtryve CodeGenRegBank::getCompositeSubRegIndex(CodeGenSubRegIndex *A, 1389fa3d789dSPierre van Houtryve CodeGenSubRegIndex *B) { 1390fa3d789dSPierre van Houtryve // Look for an existing entry. 1391fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Comp = A->compose(B); 1392fa3d789dSPierre van Houtryve if (Comp) 1393fa3d789dSPierre van Houtryve return Comp; 1394fa3d789dSPierre van Houtryve 1395fa3d789dSPierre van Houtryve // None exists, synthesize one. 1396fa3d789dSPierre van Houtryve std::string Name = A->getName() + "_then_" + B->getName(); 1397fa3d789dSPierre van Houtryve Comp = createSubRegIndex(Name, A->getNamespace()); 1398baf66ec0SCraig Topper A->addComposite(B, Comp, getHwModes()); 1399fa3d789dSPierre van Houtryve return Comp; 1400fa3d789dSPierre van Houtryve } 1401fa3d789dSPierre van Houtryve 1402fa3d789dSPierre van Houtryve CodeGenSubRegIndex *CodeGenRegBank::getConcatSubRegIndex( 1403baf66ec0SCraig Topper const SmallVector<CodeGenSubRegIndex *, 8> &Parts, 1404baf66ec0SCraig Topper const CodeGenHwModes &CGH) { 1405fa3d789dSPierre van Houtryve assert(Parts.size() > 1 && "Need two parts to concatenate"); 1406fa3d789dSPierre van Houtryve #ifndef NDEBUG 1407fa3d789dSPierre van Houtryve for (CodeGenSubRegIndex *Idx : Parts) { 1408fa3d789dSPierre van Houtryve assert(Idx->ConcatenationOf.empty() && "No transitive closure?"); 1409fa3d789dSPierre van Houtryve } 1410fa3d789dSPierre van Houtryve #endif 1411fa3d789dSPierre van Houtryve 1412fa3d789dSPierre van Houtryve // Look for an existing entry. 1413fa3d789dSPierre van Houtryve CodeGenSubRegIndex *&Idx = ConcatIdx[Parts]; 1414fa3d789dSPierre van Houtryve if (Idx) 1415fa3d789dSPierre van Houtryve return Idx; 1416fa3d789dSPierre van Houtryve 1417fa3d789dSPierre van Houtryve // None exists, synthesize one. 1418fa3d789dSPierre van Houtryve std::string Name = Parts.front()->getName(); 1419fa3d789dSPierre van Houtryve const unsigned UnknownSize = (uint16_t)-1; 1420baf66ec0SCraig Topper 1421fa3d789dSPierre van Houtryve for (unsigned i = 1, e = Parts.size(); i != e; ++i) { 1422fa3d789dSPierre van Houtryve Name += '_'; 1423fa3d789dSPierre van Houtryve Name += Parts[i]->getName(); 1424baf66ec0SCraig Topper } 1425baf66ec0SCraig Topper 1426baf66ec0SCraig Topper Idx = createSubRegIndex(Name, Parts.front()->getNamespace()); 1427baf66ec0SCraig Topper Idx->ConcatenationOf.assign(Parts.begin(), Parts.end()); 1428baf66ec0SCraig Topper 1429baf66ec0SCraig Topper unsigned NumModes = CGH.getNumModeIds(); 1430baf66ec0SCraig Topper for (unsigned M = 0; M < NumModes; ++M) { 1431baf66ec0SCraig Topper const CodeGenSubRegIndex *Part = Parts.front(); 1432baf66ec0SCraig Topper 1433baf66ec0SCraig Topper // Determine whether all parts are contiguous. 1434baf66ec0SCraig Topper bool IsContinuous = true; 1435baf66ec0SCraig Topper const SubRegRange &FirstPartRange = Part->Range.get(M); 1436baf66ec0SCraig Topper unsigned Size = FirstPartRange.Size; 1437baf66ec0SCraig Topper unsigned LastOffset = FirstPartRange.Offset; 1438baf66ec0SCraig Topper unsigned LastSize = FirstPartRange.Size; 1439baf66ec0SCraig Topper 1440baf66ec0SCraig Topper for (unsigned i = 1, e = Parts.size(); i != e; ++i) { 1441baf66ec0SCraig Topper Part = Parts[i]; 1442baf66ec0SCraig Topper Name += '_'; 1443baf66ec0SCraig Topper Name += Part->getName(); 1444baf66ec0SCraig Topper 1445baf66ec0SCraig Topper const SubRegRange &PartRange = Part->Range.get(M); 1446baf66ec0SCraig Topper if (Size == UnknownSize || PartRange.Size == UnknownSize) 1447fa3d789dSPierre van Houtryve Size = UnknownSize; 1448fa3d789dSPierre van Houtryve else 1449baf66ec0SCraig Topper Size += PartRange.Size; 1450baf66ec0SCraig Topper if (LastSize == UnknownSize || 1451baf66ec0SCraig Topper PartRange.Offset != (LastOffset + LastSize)) 1452fa3d789dSPierre van Houtryve IsContinuous = false; 1453baf66ec0SCraig Topper LastOffset = PartRange.Offset; 1454baf66ec0SCraig Topper LastSize = PartRange.Size; 1455fa3d789dSPierre van Houtryve } 1456baf66ec0SCraig Topper unsigned Offset = IsContinuous ? FirstPartRange.Offset : -1; 1457baf66ec0SCraig Topper Idx->Range.get(M) = SubRegRange(Size, Offset); 1458baf66ec0SCraig Topper } 1459baf66ec0SCraig Topper 1460fa3d789dSPierre van Houtryve return Idx; 1461fa3d789dSPierre van Houtryve } 1462fa3d789dSPierre van Houtryve 1463fa3d789dSPierre van Houtryve void CodeGenRegBank::computeComposites() { 1464fa3d789dSPierre van Houtryve using RegMap = std::map<const CodeGenRegister *, const CodeGenRegister *>; 1465fa3d789dSPierre van Houtryve 1466fa3d789dSPierre van Houtryve // Subreg -> { Reg->Reg }, where the right-hand side is the mapping from 1467fa3d789dSPierre van Houtryve // register to (sub)register associated with the action of the left-hand 1468fa3d789dSPierre van Houtryve // side subregister. 1469fa3d789dSPierre van Houtryve std::map<const CodeGenSubRegIndex *, RegMap> SubRegAction; 1470fa3d789dSPierre van Houtryve for (const CodeGenRegister &R : Registers) { 1471fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap &SM = R.getSubRegs(); 1472fa3d789dSPierre van Houtryve for (std::pair<const CodeGenSubRegIndex *, const CodeGenRegister *> P : SM) 1473fa3d789dSPierre van Houtryve SubRegAction[P.first].insert({&R, P.second}); 1474fa3d789dSPierre van Houtryve } 1475fa3d789dSPierre van Houtryve 1476fa3d789dSPierre van Houtryve // Calculate the composition of two subregisters as compositions of their 1477fa3d789dSPierre van Houtryve // associated actions. 1478fa3d789dSPierre van Houtryve auto compose = [&SubRegAction](const CodeGenSubRegIndex *Sub1, 1479fa3d789dSPierre van Houtryve const CodeGenSubRegIndex *Sub2) { 1480fa3d789dSPierre van Houtryve RegMap C; 1481fa3d789dSPierre van Houtryve const RegMap &Img1 = SubRegAction.at(Sub1); 1482fa3d789dSPierre van Houtryve const RegMap &Img2 = SubRegAction.at(Sub2); 1483fa3d789dSPierre van Houtryve for (std::pair<const CodeGenRegister *, const CodeGenRegister *> P : Img1) { 1484fa3d789dSPierre van Houtryve auto F = Img2.find(P.second); 1485fa3d789dSPierre van Houtryve if (F != Img2.end()) 1486fa3d789dSPierre van Houtryve C.insert({P.first, F->second}); 1487fa3d789dSPierre van Houtryve } 1488fa3d789dSPierre van Houtryve return C; 1489fa3d789dSPierre van Houtryve }; 1490fa3d789dSPierre van Houtryve 1491fa3d789dSPierre van Houtryve // Check if the two maps agree on the intersection of their domains. 1492fa3d789dSPierre van Houtryve auto agree = [](const RegMap &Map1, const RegMap &Map2) { 1493fa3d789dSPierre van Houtryve // Technically speaking, an empty map agrees with any other map, but 1494fa3d789dSPierre van Houtryve // this could flag false positives. We're interested in non-vacuous 1495fa3d789dSPierre van Houtryve // agreements. 1496fa3d789dSPierre van Houtryve if (Map1.empty() || Map2.empty()) 1497fa3d789dSPierre van Houtryve return false; 1498fa3d789dSPierre van Houtryve for (std::pair<const CodeGenRegister *, const CodeGenRegister *> P : Map1) { 1499fa3d789dSPierre van Houtryve auto F = Map2.find(P.first); 1500fa3d789dSPierre van Houtryve if (F == Map2.end() || P.second != F->second) 1501fa3d789dSPierre van Houtryve return false; 1502fa3d789dSPierre van Houtryve } 1503fa3d789dSPierre van Houtryve return true; 1504fa3d789dSPierre van Houtryve }; 1505fa3d789dSPierre van Houtryve 1506fa3d789dSPierre van Houtryve using CompositePair = 1507fa3d789dSPierre van Houtryve std::pair<const CodeGenSubRegIndex *, const CodeGenSubRegIndex *>; 1508fa3d789dSPierre van Houtryve SmallSet<CompositePair, 4> UserDefined; 1509fa3d789dSPierre van Houtryve for (const CodeGenSubRegIndex &Idx : SubRegIndices) 1510fa3d789dSPierre van Houtryve for (auto P : Idx.getComposites()) 1511*4e8c9d28SJay Foad UserDefined.insert({&Idx, P.first}); 1512fa3d789dSPierre van Houtryve 1513fa3d789dSPierre van Houtryve // Keep track of TopoSigs visited. We only need to visit each TopoSig once, 1514fa3d789dSPierre van Houtryve // and many registers will share TopoSigs on regular architectures. 1515fa3d789dSPierre van Houtryve BitVector TopoSigs(getNumTopoSigs()); 1516fa3d789dSPierre van Houtryve 1517fa3d789dSPierre van Houtryve for (const auto &Reg1 : Registers) { 1518fa3d789dSPierre van Houtryve // Skip identical subreg structures already processed. 1519fa3d789dSPierre van Houtryve if (TopoSigs.test(Reg1.getTopoSig())) 1520fa3d789dSPierre van Houtryve continue; 1521fa3d789dSPierre van Houtryve TopoSigs.set(Reg1.getTopoSig()); 1522fa3d789dSPierre van Houtryve 1523fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap &SRM1 = Reg1.getSubRegs(); 1524fa3d789dSPierre van Houtryve for (auto I1 : SRM1) { 1525fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Idx1 = I1.first; 1526fa3d789dSPierre van Houtryve CodeGenRegister *Reg2 = I1.second; 1527fa3d789dSPierre van Houtryve // Ignore identity compositions. 1528fa3d789dSPierre van Houtryve if (&Reg1 == Reg2) 1529fa3d789dSPierre van Houtryve continue; 1530fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs(); 1531fa3d789dSPierre van Houtryve // Try composing Idx1 with another SubRegIndex. 1532fa3d789dSPierre van Houtryve for (auto I2 : SRM2) { 1533fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Idx2 = I2.first; 1534fa3d789dSPierre van Houtryve CodeGenRegister *Reg3 = I2.second; 1535fa3d789dSPierre van Houtryve // Ignore identity compositions. 1536fa3d789dSPierre van Houtryve if (Reg2 == Reg3) 1537fa3d789dSPierre van Houtryve continue; 1538fa3d789dSPierre van Houtryve // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3. 1539fa3d789dSPierre van Houtryve CodeGenSubRegIndex *Idx3 = Reg1.getSubRegIndex(Reg3); 1540fa3d789dSPierre van Houtryve assert(Idx3 && "Sub-register doesn't have an index"); 1541fa3d789dSPierre van Houtryve 1542fa3d789dSPierre van Houtryve // Conflicting composition? Emit a warning but allow it. 1543baf66ec0SCraig Topper if (CodeGenSubRegIndex *Prev = 1544baf66ec0SCraig Topper Idx1->addComposite(Idx2, Idx3, getHwModes())) { 1545fa3d789dSPierre van Houtryve // If the composition was not user-defined, always emit a warning. 1546fa3d789dSPierre van Houtryve if (!UserDefined.count({Idx1, Idx2}) || 1547fa3d789dSPierre van Houtryve agree(compose(Idx1, Idx2), SubRegAction.at(Idx3))) 1548fa3d789dSPierre van Houtryve PrintWarning(Twine("SubRegIndex ") + Idx1->getQualifiedName() + 1549fa3d789dSPierre van Houtryve " and " + Idx2->getQualifiedName() + 1550fa3d789dSPierre van Houtryve " compose ambiguously as " + Prev->getQualifiedName() + 1551fa3d789dSPierre van Houtryve " or " + Idx3->getQualifiedName()); 1552fa3d789dSPierre van Houtryve } 1553fa3d789dSPierre van Houtryve } 1554fa3d789dSPierre van Houtryve } 1555fa3d789dSPierre van Houtryve } 1556fa3d789dSPierre van Houtryve } 1557fa3d789dSPierre van Houtryve 1558fa3d789dSPierre van Houtryve // Compute lane masks. This is similar to register units, but at the 1559fa3d789dSPierre van Houtryve // sub-register index level. Each bit in the lane mask is like a register unit 1560fa3d789dSPierre van Houtryve // class, and two lane masks will have a bit in common if two sub-register 1561fa3d789dSPierre van Houtryve // indices overlap in some register. 1562fa3d789dSPierre van Houtryve // 1563fa3d789dSPierre van Houtryve // Conservatively share a lane mask bit if two sub-register indices overlap in 1564fa3d789dSPierre van Houtryve // some registers, but not in others. That shouldn't happen a lot. 1565fa3d789dSPierre van Houtryve void CodeGenRegBank::computeSubRegLaneMasks() { 1566fa3d789dSPierre van Houtryve // First assign individual bits to all the leaf indices. 1567fa3d789dSPierre van Houtryve unsigned Bit = 0; 1568fa3d789dSPierre van Houtryve // Determine mask of lanes that cover their registers. 1569fa3d789dSPierre van Houtryve CoveringLanes = LaneBitmask::getAll(); 1570fa3d789dSPierre van Houtryve for (auto &Idx : SubRegIndices) { 1571fa3d789dSPierre van Houtryve if (Idx.getComposites().empty()) { 1572fa3d789dSPierre van Houtryve if (Bit > LaneBitmask::BitWidth) { 1573fa3d789dSPierre van Houtryve PrintFatalError( 1574fa3d789dSPierre van Houtryve Twine("Ran out of lanemask bits to represent subregister ") + 1575fa3d789dSPierre van Houtryve Idx.getName()); 1576fa3d789dSPierre van Houtryve } 1577fa3d789dSPierre van Houtryve Idx.LaneMask = LaneBitmask::getLane(Bit); 1578fa3d789dSPierre van Houtryve ++Bit; 1579fa3d789dSPierre van Houtryve } else { 1580fa3d789dSPierre van Houtryve Idx.LaneMask = LaneBitmask::getNone(); 1581fa3d789dSPierre van Houtryve } 1582fa3d789dSPierre van Houtryve } 1583fa3d789dSPierre van Houtryve 1584fa3d789dSPierre van Houtryve // Compute transformation sequences for composeSubRegIndexLaneMask. The idea 1585fa3d789dSPierre van Houtryve // here is that for each possible target subregister we look at the leafs 1586fa3d789dSPierre van Houtryve // in the subregister graph that compose for this target and create 1587fa3d789dSPierre van Houtryve // transformation sequences for the lanemasks. Each step in the sequence 1588fa3d789dSPierre van Houtryve // consists of a bitmask and a bitrotate operation. As the rotation amounts 1589fa3d789dSPierre van Houtryve // are usually the same for many subregisters we can easily combine the steps 1590fa3d789dSPierre van Houtryve // by combining the masks. 1591fa3d789dSPierre van Houtryve for (const auto &Idx : SubRegIndices) { 1592fa3d789dSPierre van Houtryve const auto &Composites = Idx.getComposites(); 1593fa3d789dSPierre van Houtryve auto &LaneTransforms = Idx.CompositionLaneMaskTransform; 1594fa3d789dSPierre van Houtryve 1595fa3d789dSPierre van Houtryve if (Composites.empty()) { 1596fa3d789dSPierre van Houtryve // Moving from a class with no subregisters we just had a single lane: 1597fa3d789dSPierre van Houtryve // The subregister must be a leaf subregister and only occupies 1 bit. 1598fa3d789dSPierre van Houtryve // Move the bit from the class without subregisters into that position. 1599fa3d789dSPierre van Houtryve unsigned DstBit = Idx.LaneMask.getHighestLane(); 1600fa3d789dSPierre van Houtryve assert(Idx.LaneMask == LaneBitmask::getLane(DstBit) && 1601fa3d789dSPierre van Houtryve "Must be a leaf subregister"); 1602fa3d789dSPierre van Houtryve MaskRolPair MaskRol = {LaneBitmask::getLane(0), (uint8_t)DstBit}; 1603fa3d789dSPierre van Houtryve LaneTransforms.push_back(MaskRol); 1604fa3d789dSPierre van Houtryve } else { 1605fa3d789dSPierre van Houtryve // Go through all leaf subregisters and find the ones that compose with 1606fa3d789dSPierre van Houtryve // Idx. These make out all possible valid bits in the lane mask we want to 1607fa3d789dSPierre van Houtryve // transform. Looking only at the leafs ensure that only a single bit in 1608fa3d789dSPierre van Houtryve // the mask is set. 1609fa3d789dSPierre van Houtryve unsigned NextBit = 0; 1610fa3d789dSPierre van Houtryve for (auto &Idx2 : SubRegIndices) { 1611fa3d789dSPierre van Houtryve // Skip non-leaf subregisters. 1612fa3d789dSPierre van Houtryve if (!Idx2.getComposites().empty()) 1613fa3d789dSPierre van Houtryve continue; 1614fa3d789dSPierre van Houtryve // Replicate the behaviour from the lane mask generation loop above. 1615fa3d789dSPierre van Houtryve unsigned SrcBit = NextBit; 1616fa3d789dSPierre van Houtryve LaneBitmask SrcMask = LaneBitmask::getLane(SrcBit); 1617fa3d789dSPierre van Houtryve if (NextBit < LaneBitmask::BitWidth - 1) 1618fa3d789dSPierre van Houtryve ++NextBit; 1619fa3d789dSPierre van Houtryve assert(Idx2.LaneMask == SrcMask); 1620fa3d789dSPierre van Houtryve 1621fa3d789dSPierre van Houtryve // Get the composed subregister if there is any. 1622fa3d789dSPierre van Houtryve auto C = Composites.find(&Idx2); 1623fa3d789dSPierre van Houtryve if (C == Composites.end()) 1624fa3d789dSPierre van Houtryve continue; 1625fa3d789dSPierre van Houtryve const CodeGenSubRegIndex *Composite = C->second; 1626fa3d789dSPierre van Houtryve // The Composed subreg should be a leaf subreg too 1627fa3d789dSPierre van Houtryve assert(Composite->getComposites().empty()); 1628fa3d789dSPierre van Houtryve 1629fa3d789dSPierre van Houtryve // Create Mask+Rotate operation and merge with existing ops if possible. 1630fa3d789dSPierre van Houtryve unsigned DstBit = Composite->LaneMask.getHighestLane(); 1631fa3d789dSPierre van Houtryve int Shift = DstBit - SrcBit; 1632fa3d789dSPierre van Houtryve uint8_t RotateLeft = 1633fa3d789dSPierre van Houtryve Shift >= 0 ? (uint8_t)Shift : LaneBitmask::BitWidth + Shift; 1634fa3d789dSPierre van Houtryve for (auto &I : LaneTransforms) { 1635fa3d789dSPierre van Houtryve if (I.RotateLeft == RotateLeft) { 1636fa3d789dSPierre van Houtryve I.Mask |= SrcMask; 1637fa3d789dSPierre van Houtryve SrcMask = LaneBitmask::getNone(); 1638fa3d789dSPierre van Houtryve } 1639fa3d789dSPierre van Houtryve } 1640fa3d789dSPierre van Houtryve if (SrcMask.any()) { 1641fa3d789dSPierre van Houtryve MaskRolPair MaskRol = {SrcMask, RotateLeft}; 1642fa3d789dSPierre van Houtryve LaneTransforms.push_back(MaskRol); 1643fa3d789dSPierre van Houtryve } 1644fa3d789dSPierre van Houtryve } 1645fa3d789dSPierre van Houtryve } 1646fa3d789dSPierre van Houtryve 1647fa3d789dSPierre van Houtryve // Optimize if the transformation consists of one step only: Set mask to 1648fa3d789dSPierre van Houtryve // 0xffffffff (including some irrelevant invalid bits) so that it should 1649fa3d789dSPierre van Houtryve // merge with more entries later while compressing the table. 1650fa3d789dSPierre van Houtryve if (LaneTransforms.size() == 1) 1651fa3d789dSPierre van Houtryve LaneTransforms[0].Mask = LaneBitmask::getAll(); 1652fa3d789dSPierre van Houtryve 1653fa3d789dSPierre van Houtryve // Further compression optimization: For invalid compositions resulting 1654fa3d789dSPierre van Houtryve // in a sequence with 0 entries we can just pick any other. Choose 1655fa3d789dSPierre van Houtryve // Mask 0xffffffff with Rotation 0. 1656fa3d789dSPierre van Houtryve if (LaneTransforms.size() == 0) { 1657fa3d789dSPierre van Houtryve MaskRolPair P = {LaneBitmask::getAll(), 0}; 1658fa3d789dSPierre van Houtryve LaneTransforms.push_back(P); 1659fa3d789dSPierre van Houtryve } 1660fa3d789dSPierre van Houtryve } 1661fa3d789dSPierre van Houtryve 1662fa3d789dSPierre van Houtryve // FIXME: What if ad-hoc aliasing introduces overlaps that aren't represented 1663fa3d789dSPierre van Houtryve // by the sub-register graph? This doesn't occur in any known targets. 1664fa3d789dSPierre van Houtryve 1665fa3d789dSPierre van Houtryve // Inherit lanes from composites. 1666fa3d789dSPierre van Houtryve for (const auto &Idx : SubRegIndices) { 1667fa3d789dSPierre van Houtryve LaneBitmask Mask = Idx.computeLaneMask(); 1668fa3d789dSPierre van Houtryve // If some super-registers without CoveredBySubRegs use this index, we can 1669fa3d789dSPierre van Houtryve // no longer assume that the lanes are covering their registers. 1670fa3d789dSPierre van Houtryve if (!Idx.AllSuperRegsCovered) 1671fa3d789dSPierre van Houtryve CoveringLanes &= ~Mask; 1672fa3d789dSPierre van Houtryve } 1673fa3d789dSPierre van Houtryve 1674fa3d789dSPierre van Houtryve // Compute lane mask combinations for register classes. 1675fa3d789dSPierre van Houtryve for (auto &RegClass : RegClasses) { 1676fa3d789dSPierre van Houtryve LaneBitmask LaneMask; 1677fa3d789dSPierre van Houtryve for (const auto &SubRegIndex : SubRegIndices) { 1678fa3d789dSPierre van Houtryve if (RegClass.getSubClassWithSubReg(&SubRegIndex) == nullptr) 1679fa3d789dSPierre van Houtryve continue; 1680fa3d789dSPierre van Houtryve LaneMask |= SubRegIndex.LaneMask; 1681fa3d789dSPierre van Houtryve } 1682fa3d789dSPierre van Houtryve 1683fa3d789dSPierre van Houtryve // For classes without any subregisters set LaneMask to 1 instead of 0. 1684fa3d789dSPierre van Houtryve // This makes it easier for client code to handle classes uniformly. 1685fa3d789dSPierre van Houtryve if (LaneMask.none()) 1686fa3d789dSPierre van Houtryve LaneMask = LaneBitmask::getLane(0); 1687fa3d789dSPierre van Houtryve 1688fa3d789dSPierre van Houtryve RegClass.LaneMask = LaneMask; 1689fa3d789dSPierre van Houtryve } 1690fa3d789dSPierre van Houtryve } 1691fa3d789dSPierre van Houtryve 1692fa3d789dSPierre van Houtryve namespace { 1693fa3d789dSPierre van Houtryve 1694fa3d789dSPierre van Houtryve // UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is 1695fa3d789dSPierre van Houtryve // the transitive closure of the union of overlapping register 1696fa3d789dSPierre van Houtryve // classes. Together, the UberRegSets form a partition of the registers. If we 1697fa3d789dSPierre van Houtryve // consider overlapping register classes to be connected, then each UberRegSet 1698fa3d789dSPierre van Houtryve // is a set of connected components. 1699fa3d789dSPierre van Houtryve // 1700fa3d789dSPierre van Houtryve // An UberRegSet will likely be a horizontal slice of register names of 1701fa3d789dSPierre van Houtryve // the same width. Nontrivial subregisters should then be in a separate 1702fa3d789dSPierre van Houtryve // UberRegSet. But this property isn't required for valid computation of 1703fa3d789dSPierre van Houtryve // register unit weights. 1704fa3d789dSPierre van Houtryve // 1705fa3d789dSPierre van Houtryve // A Weight field caches the max per-register unit weight in each UberRegSet. 1706fa3d789dSPierre van Houtryve // 1707fa3d789dSPierre van Houtryve // A set of SingularDeterminants flags single units of some register in this set 1708fa3d789dSPierre van Houtryve // for which the unit weight equals the set weight. These units should not have 1709fa3d789dSPierre van Houtryve // their weight increased. 1710fa3d789dSPierre van Houtryve struct UberRegSet { 1711fa3d789dSPierre van Houtryve CodeGenRegister::Vec Regs; 1712fa3d789dSPierre van Houtryve unsigned Weight = 0; 1713fa3d789dSPierre van Houtryve CodeGenRegister::RegUnitList SingularDeterminants; 1714fa3d789dSPierre van Houtryve 1715fa3d789dSPierre van Houtryve UberRegSet() = default; 1716fa3d789dSPierre van Houtryve }; 1717fa3d789dSPierre van Houtryve 1718fa3d789dSPierre van Houtryve } // end anonymous namespace 1719fa3d789dSPierre van Houtryve 1720fa3d789dSPierre van Houtryve // Partition registers into UberRegSets, where each set is the transitive 1721fa3d789dSPierre van Houtryve // closure of the union of overlapping register classes. 1722fa3d789dSPierre van Houtryve // 1723fa3d789dSPierre van Houtryve // UberRegSets[0] is a special non-allocatable set. 1724fa3d789dSPierre van Houtryve static void computeUberSets(std::vector<UberRegSet> &UberSets, 1725fa3d789dSPierre van Houtryve std::vector<UberRegSet *> &RegSets, 1726fa3d789dSPierre van Houtryve CodeGenRegBank &RegBank) { 1727fa3d789dSPierre van Houtryve const auto &Registers = RegBank.getRegisters(); 1728fa3d789dSPierre van Houtryve 1729fa3d789dSPierre van Houtryve // The Register EnumValue is one greater than its index into Registers. 1730fa3d789dSPierre van Houtryve assert(Registers.size() == Registers.back().EnumValue && 1731fa3d789dSPierre van Houtryve "register enum value mismatch"); 1732fa3d789dSPierre van Houtryve 1733fa3d789dSPierre van Houtryve // For simplicitly make the SetID the same as EnumValue. 1734fa3d789dSPierre van Houtryve IntEqClasses UberSetIDs(Registers.size() + 1); 1735fa3d789dSPierre van Houtryve BitVector AllocatableRegs(Registers.size() + 1); 1736fa3d789dSPierre van Houtryve for (auto &RegClass : RegBank.getRegClasses()) { 1737fa3d789dSPierre van Houtryve if (!RegClass.Allocatable) 1738fa3d789dSPierre van Houtryve continue; 1739fa3d789dSPierre van Houtryve 1740fa3d789dSPierre van Houtryve const CodeGenRegister::Vec &Regs = RegClass.getMembers(); 1741fa3d789dSPierre van Houtryve if (Regs.empty()) 1742fa3d789dSPierre van Houtryve continue; 1743fa3d789dSPierre van Houtryve 1744fa3d789dSPierre van Houtryve unsigned USetID = UberSetIDs.findLeader((*Regs.begin())->EnumValue); 1745fa3d789dSPierre van Houtryve assert(USetID && "register number 0 is invalid"); 1746fa3d789dSPierre van Houtryve 1747fa3d789dSPierre van Houtryve AllocatableRegs.set((*Regs.begin())->EnumValue); 1748fa3d789dSPierre van Houtryve for (const CodeGenRegister *CGR : llvm::drop_begin(Regs)) { 1749fa3d789dSPierre van Houtryve AllocatableRegs.set(CGR->EnumValue); 1750fa3d789dSPierre van Houtryve UberSetIDs.join(USetID, CGR->EnumValue); 1751fa3d789dSPierre van Houtryve } 1752fa3d789dSPierre van Houtryve } 1753fa3d789dSPierre van Houtryve // Combine non-allocatable regs. 1754fa3d789dSPierre van Houtryve for (const auto &Reg : Registers) { 1755fa3d789dSPierre van Houtryve unsigned RegNum = Reg.EnumValue; 1756fa3d789dSPierre van Houtryve if (AllocatableRegs.test(RegNum)) 1757fa3d789dSPierre van Houtryve continue; 1758fa3d789dSPierre van Houtryve 1759fa3d789dSPierre van Houtryve UberSetIDs.join(0, RegNum); 1760fa3d789dSPierre van Houtryve } 1761fa3d789dSPierre van Houtryve UberSetIDs.compress(); 1762fa3d789dSPierre van Houtryve 1763fa3d789dSPierre van Houtryve // Make the first UberSet a special unallocatable set. 1764fa3d789dSPierre van Houtryve unsigned ZeroID = UberSetIDs[0]; 1765fa3d789dSPierre van Houtryve 1766fa3d789dSPierre van Houtryve // Insert Registers into the UberSets formed by union-find. 1767fa3d789dSPierre van Houtryve // Do not resize after this. 1768fa3d789dSPierre van Houtryve UberSets.resize(UberSetIDs.getNumClasses()); 1769fa3d789dSPierre van Houtryve unsigned i = 0; 1770fa3d789dSPierre van Houtryve for (const CodeGenRegister &Reg : Registers) { 1771fa3d789dSPierre van Houtryve unsigned USetID = UberSetIDs[Reg.EnumValue]; 1772fa3d789dSPierre van Houtryve if (!USetID) 1773fa3d789dSPierre van Houtryve USetID = ZeroID; 1774fa3d789dSPierre van Houtryve else if (USetID == ZeroID) 1775fa3d789dSPierre van Houtryve USetID = 0; 1776fa3d789dSPierre van Houtryve 1777fa3d789dSPierre van Houtryve UberRegSet *USet = &UberSets[USetID]; 1778fa3d789dSPierre van Houtryve USet->Regs.push_back(&Reg); 1779fa3d789dSPierre van Houtryve RegSets[i++] = USet; 1780fa3d789dSPierre van Houtryve } 1781fa3d789dSPierre van Houtryve } 1782fa3d789dSPierre van Houtryve 1783fa3d789dSPierre van Houtryve // Recompute each UberSet weight after changing unit weights. 1784fa3d789dSPierre van Houtryve static void computeUberWeights(std::vector<UberRegSet> &UberSets, 1785fa3d789dSPierre van Houtryve CodeGenRegBank &RegBank) { 1786fa3d789dSPierre van Houtryve // Skip the first unallocatable set. 1787fa3d789dSPierre van Houtryve for (std::vector<UberRegSet>::iterator I = std::next(UberSets.begin()), 1788fa3d789dSPierre van Houtryve E = UberSets.end(); 1789fa3d789dSPierre van Houtryve I != E; ++I) { 1790fa3d789dSPierre van Houtryve 1791fa3d789dSPierre van Houtryve // Initialize all unit weights in this set, and remember the max units/reg. 1792fa3d789dSPierre van Houtryve const CodeGenRegister *Reg = nullptr; 1793fa3d789dSPierre van Houtryve unsigned MaxWeight = 0, Weight = 0; 1794fa3d789dSPierre van Houtryve for (RegUnitIterator UnitI(I->Regs); UnitI.isValid(); ++UnitI) { 1795fa3d789dSPierre van Houtryve if (Reg != UnitI.getReg()) { 1796fa3d789dSPierre van Houtryve if (Weight > MaxWeight) 1797fa3d789dSPierre van Houtryve MaxWeight = Weight; 1798fa3d789dSPierre van Houtryve Reg = UnitI.getReg(); 1799fa3d789dSPierre van Houtryve Weight = 0; 1800fa3d789dSPierre van Houtryve } 1801fa3d789dSPierre van Houtryve if (!RegBank.getRegUnit(*UnitI).Artificial) { 1802fa3d789dSPierre van Houtryve unsigned UWeight = RegBank.getRegUnit(*UnitI).Weight; 1803fa3d789dSPierre van Houtryve if (!UWeight) { 1804fa3d789dSPierre van Houtryve UWeight = 1; 1805fa3d789dSPierre van Houtryve RegBank.increaseRegUnitWeight(*UnitI, UWeight); 1806fa3d789dSPierre van Houtryve } 1807fa3d789dSPierre van Houtryve Weight += UWeight; 1808fa3d789dSPierre van Houtryve } 1809fa3d789dSPierre van Houtryve } 1810fa3d789dSPierre van Houtryve if (Weight > MaxWeight) 1811fa3d789dSPierre van Houtryve MaxWeight = Weight; 1812fa3d789dSPierre van Houtryve if (I->Weight != MaxWeight) { 1813fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "UberSet " << I - UberSets.begin() << " Weight " 1814fa3d789dSPierre van Houtryve << MaxWeight; 1815fa3d789dSPierre van Houtryve for (auto &Unit 1816fa3d789dSPierre van Houtryve : I->Regs) dbgs() 1817fa3d789dSPierre van Houtryve << " " << Unit->getName(); 1818fa3d789dSPierre van Houtryve dbgs() << "\n"); 1819fa3d789dSPierre van Houtryve // Update the set weight. 1820fa3d789dSPierre van Houtryve I->Weight = MaxWeight; 1821fa3d789dSPierre van Houtryve } 1822fa3d789dSPierre van Houtryve 1823fa3d789dSPierre van Houtryve // Find singular determinants. 1824fa3d789dSPierre van Houtryve for (const auto R : I->Regs) { 1825fa3d789dSPierre van Houtryve if (R->getRegUnits().count() == 1 && R->getWeight(RegBank) == I->Weight) { 1826fa3d789dSPierre van Houtryve I->SingularDeterminants |= R->getRegUnits(); 1827fa3d789dSPierre van Houtryve } 1828fa3d789dSPierre van Houtryve } 1829fa3d789dSPierre van Houtryve } 1830fa3d789dSPierre van Houtryve } 1831fa3d789dSPierre van Houtryve 1832fa3d789dSPierre van Houtryve // normalizeWeight is a computeRegUnitWeights helper that adjusts the weight of 1833fa3d789dSPierre van Houtryve // a register and its subregisters so that they have the same weight as their 1834fa3d789dSPierre van Houtryve // UberSet. Self-recursion processes the subregister tree in postorder so 1835fa3d789dSPierre van Houtryve // subregisters are normalized first. 1836fa3d789dSPierre van Houtryve // 1837fa3d789dSPierre van Houtryve // Side effects: 1838fa3d789dSPierre van Houtryve // - creates new adopted register units 1839fa3d789dSPierre van Houtryve // - causes superregisters to inherit adopted units 1840fa3d789dSPierre van Houtryve // - increases the weight of "singular" units 1841fa3d789dSPierre van Houtryve // - induces recomputation of UberWeights. 1842fa3d789dSPierre van Houtryve static bool normalizeWeight(CodeGenRegister *Reg, 1843fa3d789dSPierre van Houtryve std::vector<UberRegSet> &UberSets, 1844fa3d789dSPierre van Houtryve std::vector<UberRegSet *> &RegSets, 1845fa3d789dSPierre van Houtryve BitVector &NormalRegs, 1846fa3d789dSPierre van Houtryve CodeGenRegister::RegUnitList &NormalUnits, 1847fa3d789dSPierre van Houtryve CodeGenRegBank &RegBank) { 1848fa3d789dSPierre van Houtryve NormalRegs.resize(std::max(Reg->EnumValue + 1, NormalRegs.size())); 1849fa3d789dSPierre van Houtryve if (NormalRegs.test(Reg->EnumValue)) 1850fa3d789dSPierre van Houtryve return false; 1851fa3d789dSPierre van Houtryve NormalRegs.set(Reg->EnumValue); 1852fa3d789dSPierre van Houtryve 1853fa3d789dSPierre van Houtryve bool Changed = false; 1854fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs(); 1855fa3d789dSPierre van Houtryve for (auto SRI : SRM) { 1856fa3d789dSPierre van Houtryve if (SRI.second == Reg) 1857fa3d789dSPierre van Houtryve continue; // self-cycles happen 1858fa3d789dSPierre van Houtryve 1859fa3d789dSPierre van Houtryve Changed |= normalizeWeight(SRI.second, UberSets, RegSets, NormalRegs, 1860fa3d789dSPierre van Houtryve NormalUnits, RegBank); 1861fa3d789dSPierre van Houtryve } 1862fa3d789dSPierre van Houtryve // Postorder register normalization. 1863fa3d789dSPierre van Houtryve 1864fa3d789dSPierre van Houtryve // Inherit register units newly adopted by subregisters. 1865fa3d789dSPierre van Houtryve if (Reg->inheritRegUnits(RegBank)) 1866fa3d789dSPierre van Houtryve computeUberWeights(UberSets, RegBank); 1867fa3d789dSPierre van Houtryve 1868fa3d789dSPierre van Houtryve // Check if this register is too skinny for its UberRegSet. 1869fa3d789dSPierre van Houtryve UberRegSet *UberSet = RegSets[RegBank.getRegIndex(Reg)]; 1870fa3d789dSPierre van Houtryve 1871fa3d789dSPierre van Houtryve unsigned RegWeight = Reg->getWeight(RegBank); 1872fa3d789dSPierre van Houtryve if (UberSet->Weight > RegWeight) { 1873fa3d789dSPierre van Houtryve // A register unit's weight can be adjusted only if it is the singular unit 1874fa3d789dSPierre van Houtryve // for this register, has not been used to normalize a subregister's set, 1875fa3d789dSPierre van Houtryve // and has not already been used to singularly determine this UberRegSet. 1876fa3d789dSPierre van Houtryve unsigned AdjustUnit = *Reg->getRegUnits().begin(); 1877fa3d789dSPierre van Houtryve if (Reg->getRegUnits().count() != 1 || NormalUnits.test(AdjustUnit) || 1878fa3d789dSPierre van Houtryve UberSet->SingularDeterminants.test(AdjustUnit)) { 1879fa3d789dSPierre van Houtryve // We don't have an adjustable unit, so adopt a new one. 1880fa3d789dSPierre van Houtryve AdjustUnit = RegBank.newRegUnit(UberSet->Weight - RegWeight); 1881fa3d789dSPierre van Houtryve Reg->adoptRegUnit(AdjustUnit); 1882fa3d789dSPierre van Houtryve // Adopting a unit does not immediately require recomputing set weights. 1883fa3d789dSPierre van Houtryve } else { 1884fa3d789dSPierre van Houtryve // Adjust the existing single unit. 1885fa3d789dSPierre van Houtryve if (!RegBank.getRegUnit(AdjustUnit).Artificial) 1886fa3d789dSPierre van Houtryve RegBank.increaseRegUnitWeight(AdjustUnit, UberSet->Weight - RegWeight); 1887fa3d789dSPierre van Houtryve // The unit may be shared among sets and registers within this set. 1888fa3d789dSPierre van Houtryve computeUberWeights(UberSets, RegBank); 1889fa3d789dSPierre van Houtryve } 1890fa3d789dSPierre van Houtryve Changed = true; 1891fa3d789dSPierre van Houtryve } 1892fa3d789dSPierre van Houtryve 1893fa3d789dSPierre van Houtryve // Mark these units normalized so superregisters can't change their weights. 1894fa3d789dSPierre van Houtryve NormalUnits |= Reg->getRegUnits(); 1895fa3d789dSPierre van Houtryve 1896fa3d789dSPierre van Houtryve return Changed; 1897fa3d789dSPierre van Houtryve } 1898fa3d789dSPierre van Houtryve 1899fa3d789dSPierre van Houtryve // Compute a weight for each register unit created during getSubRegs. 1900fa3d789dSPierre van Houtryve // 1901fa3d789dSPierre van Houtryve // The goal is that two registers in the same class will have the same weight, 1902fa3d789dSPierre van Houtryve // where each register's weight is defined as sum of its units' weights. 1903fa3d789dSPierre van Houtryve void CodeGenRegBank::computeRegUnitWeights() { 1904fa3d789dSPierre van Houtryve std::vector<UberRegSet> UberSets; 1905fa3d789dSPierre van Houtryve std::vector<UberRegSet *> RegSets(Registers.size()); 1906fa3d789dSPierre van Houtryve computeUberSets(UberSets, RegSets, *this); 1907fa3d789dSPierre van Houtryve // UberSets and RegSets are now immutable. 1908fa3d789dSPierre van Houtryve 1909fa3d789dSPierre van Houtryve computeUberWeights(UberSets, *this); 1910fa3d789dSPierre van Houtryve 1911fa3d789dSPierre van Houtryve // Iterate over each Register, normalizing the unit weights until reaching 1912fa3d789dSPierre van Houtryve // a fix point. 1913fa3d789dSPierre van Houtryve unsigned NumIters = 0; 1914fa3d789dSPierre van Houtryve for (bool Changed = true; Changed; ++NumIters) { 1915fa3d789dSPierre van Houtryve assert(NumIters <= NumNativeRegUnits && "Runaway register unit weights"); 1916fa3d789dSPierre van Houtryve (void)NumIters; 1917fa3d789dSPierre van Houtryve Changed = false; 1918fa3d789dSPierre van Houtryve for (auto &Reg : Registers) { 1919fa3d789dSPierre van Houtryve CodeGenRegister::RegUnitList NormalUnits; 1920fa3d789dSPierre van Houtryve BitVector NormalRegs; 1921fa3d789dSPierre van Houtryve Changed |= normalizeWeight(&Reg, UberSets, RegSets, NormalRegs, 1922fa3d789dSPierre van Houtryve NormalUnits, *this); 1923fa3d789dSPierre van Houtryve } 1924fa3d789dSPierre van Houtryve } 1925fa3d789dSPierre van Houtryve } 1926fa3d789dSPierre van Houtryve 1927fa3d789dSPierre van Houtryve // Find a set in UniqueSets with the same elements as Set. 1928fa3d789dSPierre van Houtryve // Return an iterator into UniqueSets. 1929fa3d789dSPierre van Houtryve static std::vector<RegUnitSet>::const_iterator 1930fa3d789dSPierre van Houtryve findRegUnitSet(const std::vector<RegUnitSet> &UniqueSets, 1931fa3d789dSPierre van Houtryve const RegUnitSet &Set) { 1932fa3d789dSPierre van Houtryve return find_if(UniqueSets, 1933fa3d789dSPierre van Houtryve [&Set](const RegUnitSet &I) { return I.Units == Set.Units; }); 1934fa3d789dSPierre van Houtryve } 1935fa3d789dSPierre van Houtryve 1936fa3d789dSPierre van Houtryve // Return true if the RUSubSet is a subset of RUSuperSet. 1937fa3d789dSPierre van Houtryve static bool isRegUnitSubSet(const std::vector<unsigned> &RUSubSet, 1938fa3d789dSPierre van Houtryve const std::vector<unsigned> &RUSuperSet) { 1939fa3d789dSPierre van Houtryve return std::includes(RUSuperSet.begin(), RUSuperSet.end(), RUSubSet.begin(), 1940fa3d789dSPierre van Houtryve RUSubSet.end()); 1941fa3d789dSPierre van Houtryve } 1942fa3d789dSPierre van Houtryve 1943fa3d789dSPierre van Houtryve /// Iteratively prune unit sets. Prune subsets that are close to the superset, 1944fa3d789dSPierre van Houtryve /// but with one or two registers removed. We occasionally have registers like 1945fa3d789dSPierre van Houtryve /// APSR and PC thrown in with the general registers. We also see many 1946fa3d789dSPierre van Houtryve /// special-purpose register subsets, such as tail-call and Thumb 1947fa3d789dSPierre van Houtryve /// encodings. Generating all possible overlapping sets is combinatorial and 1948fa3d789dSPierre van Houtryve /// overkill for modeling pressure. Ideally we could fix this statically in 1949fa3d789dSPierre van Houtryve /// tablegen by (1) having the target define register classes that only include 1950fa3d789dSPierre van Houtryve /// the allocatable registers and marking other classes as non-allocatable and 1951fa3d789dSPierre van Houtryve /// (2) having a way to mark special purpose classes as "don't-care" classes for 1952fa3d789dSPierre van Houtryve /// the purpose of pressure. However, we make an attempt to handle targets that 1953fa3d789dSPierre van Houtryve /// are not nicely defined by merging nearly identical register unit sets 1954fa3d789dSPierre van Houtryve /// statically. This generates smaller tables. Then, dynamically, we adjust the 1955fa3d789dSPierre van Houtryve /// set limit by filtering the reserved registers. 1956fa3d789dSPierre van Houtryve /// 1957fa3d789dSPierre van Houtryve /// Merge sets only if the units have the same weight. For example, on ARM, 1958fa3d789dSPierre van Houtryve /// Q-tuples with ssub index 0 include all S regs but also include D16+. We 1959fa3d789dSPierre van Houtryve /// should not expand the S set to include D regs. 1960fa3d789dSPierre van Houtryve void CodeGenRegBank::pruneUnitSets() { 1961fa3d789dSPierre van Houtryve assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets"); 1962fa3d789dSPierre van Houtryve 1963fa3d789dSPierre van Houtryve // Form an equivalence class of UnitSets with no significant difference. 1964fa3d789dSPierre van Houtryve std::vector<unsigned> SuperSetIDs; 1965fa3d789dSPierre van Houtryve for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size(); SubIdx != EndIdx; 1966fa3d789dSPierre van Houtryve ++SubIdx) { 1967fa3d789dSPierre van Houtryve const RegUnitSet &SubSet = RegUnitSets[SubIdx]; 1968fa3d789dSPierre van Houtryve unsigned SuperIdx = 0; 1969fa3d789dSPierre van Houtryve for (; SuperIdx != EndIdx; ++SuperIdx) { 1970fa3d789dSPierre van Houtryve if (SuperIdx == SubIdx) 1971fa3d789dSPierre van Houtryve continue; 1972fa3d789dSPierre van Houtryve 1973fa3d789dSPierre van Houtryve unsigned UnitWeight = RegUnits[SubSet.Units[0]].Weight; 1974fa3d789dSPierre van Houtryve const RegUnitSet &SuperSet = RegUnitSets[SuperIdx]; 1975fa3d789dSPierre van Houtryve if (isRegUnitSubSet(SubSet.Units, SuperSet.Units) && 1976fa3d789dSPierre van Houtryve (SubSet.Units.size() + 3 > SuperSet.Units.size()) && 1977fa3d789dSPierre van Houtryve UnitWeight == RegUnits[SuperSet.Units[0]].Weight && 1978fa3d789dSPierre van Houtryve UnitWeight == RegUnits[SuperSet.Units.back()].Weight) { 1979fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "UnitSet " << SubIdx << " subsumed by " << SuperIdx 1980fa3d789dSPierre van Houtryve << "\n"); 1981fa3d789dSPierre van Houtryve // We can pick any of the set names for the merged set. Go for the 1982fa3d789dSPierre van Houtryve // shortest one to avoid picking the name of one of the classes that are 1983fa3d789dSPierre van Houtryve // artificially created by tablegen. So "FPR128_lo" instead of 1984fa3d789dSPierre van Houtryve // "QQQQ_with_qsub3_in_FPR128_lo". 1985fa3d789dSPierre van Houtryve if (RegUnitSets[SubIdx].Name.size() < RegUnitSets[SuperIdx].Name.size()) 1986fa3d789dSPierre van Houtryve RegUnitSets[SuperIdx].Name = RegUnitSets[SubIdx].Name; 1987fa3d789dSPierre van Houtryve break; 1988fa3d789dSPierre van Houtryve } 1989fa3d789dSPierre van Houtryve } 1990fa3d789dSPierre van Houtryve if (SuperIdx == EndIdx) 1991fa3d789dSPierre van Houtryve SuperSetIDs.push_back(SubIdx); 1992fa3d789dSPierre van Houtryve } 1993fa3d789dSPierre van Houtryve // Populate PrunedUnitSets with each equivalence class's superset. 1994fa3d789dSPierre van Houtryve std::vector<RegUnitSet> PrunedUnitSets; 1995fa3d789dSPierre van Houtryve PrunedUnitSets.reserve(SuperSetIDs.size()); 1996fa3d789dSPierre van Houtryve for (unsigned i = 0, e = SuperSetIDs.size(); i != e; ++i) { 1997fa3d789dSPierre van Houtryve unsigned SuperIdx = SuperSetIDs[i]; 1998fa3d789dSPierre van Houtryve PrunedUnitSets.emplace_back(RegUnitSets[SuperIdx].Name); 1999fa3d789dSPierre van Houtryve PrunedUnitSets.back().Units = std::move(RegUnitSets[SuperIdx].Units); 2000fa3d789dSPierre van Houtryve } 2001fa3d789dSPierre van Houtryve RegUnitSets = std::move(PrunedUnitSets); 2002fa3d789dSPierre van Houtryve } 2003fa3d789dSPierre van Houtryve 2004fa3d789dSPierre van Houtryve // Create a RegUnitSet for each RegClass that contains all units in the class 2005fa3d789dSPierre van Houtryve // including adopted units that are necessary to model register pressure. Then 2006fa3d789dSPierre van Houtryve // iteratively compute RegUnitSets such that the union of any two overlapping 2007fa3d789dSPierre van Houtryve // RegUnitSets is repreresented. 2008fa3d789dSPierre van Houtryve // 2009fa3d789dSPierre van Houtryve // RegisterInfoEmitter will map each RegClass to its RegUnitClass and any 2010fa3d789dSPierre van Houtryve // RegUnitSet that is a superset of that RegUnitClass. 2011fa3d789dSPierre van Houtryve void CodeGenRegBank::computeRegUnitSets() { 2012fa3d789dSPierre van Houtryve assert(RegUnitSets.empty() && "dirty RegUnitSets"); 2013fa3d789dSPierre van Houtryve 2014fa3d789dSPierre van Houtryve // Compute a unique RegUnitSet for each RegClass. 2015fa3d789dSPierre van Houtryve auto &RegClasses = getRegClasses(); 2016fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) { 2017fa3d789dSPierre van Houtryve if (!RC.Allocatable || RC.Artificial || !RC.GeneratePressureSet) 2018fa3d789dSPierre van Houtryve continue; 2019fa3d789dSPierre van Houtryve 2020fa3d789dSPierre van Houtryve // Compute a sorted list of units in this class. 2021fa3d789dSPierre van Houtryve RegUnitSet RUSet(RC.getName()); 2022fa3d789dSPierre van Houtryve RC.buildRegUnitSet(*this, RUSet.Units); 2023fa3d789dSPierre van Houtryve 2024fa3d789dSPierre van Houtryve // Find an existing RegUnitSet. 2025fa3d789dSPierre van Houtryve if (findRegUnitSet(RegUnitSets, RUSet) == RegUnitSets.end()) 2026fa3d789dSPierre van Houtryve RegUnitSets.push_back(std::move(RUSet)); 2027fa3d789dSPierre van Houtryve } 2028fa3d789dSPierre van Houtryve 2029fa3d789dSPierre van Houtryve if (RegUnitSets.empty()) 2030fa3d789dSPierre van Houtryve PrintFatalError("RegUnitSets cannot be empty!"); 2031fa3d789dSPierre van Houtryve 2032fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "\nBefore pruning:\n"; for (unsigned USIdx = 0, 2033fa3d789dSPierre van Houtryve USEnd = RegUnitSets.size(); 2034fa3d789dSPierre van Houtryve USIdx < USEnd; ++USIdx) { 2035fa3d789dSPierre van Houtryve dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":"; 2036fa3d789dSPierre van Houtryve for (auto &U : RegUnitSets[USIdx].Units) 2037fa3d789dSPierre van Houtryve printRegUnitName(U); 2038fa3d789dSPierre van Houtryve dbgs() << "\n"; 2039fa3d789dSPierre van Houtryve }); 2040fa3d789dSPierre van Houtryve 2041fa3d789dSPierre van Houtryve // Iteratively prune unit sets. 2042fa3d789dSPierre van Houtryve pruneUnitSets(); 2043fa3d789dSPierre van Houtryve 2044fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "\nBefore union:\n"; for (unsigned USIdx = 0, 2045fa3d789dSPierre van Houtryve USEnd = RegUnitSets.size(); 2046fa3d789dSPierre van Houtryve USIdx < USEnd; ++USIdx) { 2047fa3d789dSPierre van Houtryve dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":"; 2048fa3d789dSPierre van Houtryve for (auto &U : RegUnitSets[USIdx].Units) 2049fa3d789dSPierre van Houtryve printRegUnitName(U); 2050fa3d789dSPierre van Houtryve dbgs() << "\n"; 2051fa3d789dSPierre van Houtryve } dbgs() << "\nUnion sets:\n"); 2052fa3d789dSPierre van Houtryve 2053fa3d789dSPierre van Houtryve // Iterate over all unit sets, including new ones added by this loop. 2054fa3d789dSPierre van Houtryve unsigned NumRegUnitSubSets = RegUnitSets.size(); 2055fa3d789dSPierre van Houtryve for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) { 2056fa3d789dSPierre van Houtryve // In theory, this is combinatorial. In practice, it needs to be bounded 2057fa3d789dSPierre van Houtryve // by a small number of sets for regpressure to be efficient. 2058fa3d789dSPierre van Houtryve // If the assert is hit, we need to implement pruning. 2059fa3d789dSPierre van Houtryve assert(Idx < (2 * NumRegUnitSubSets) && "runaway unit set inference"); 2060fa3d789dSPierre van Houtryve 2061fa3d789dSPierre van Houtryve // Compare new sets with all original classes. 2062fa3d789dSPierre van Houtryve for (unsigned SearchIdx = (Idx >= NumRegUnitSubSets) ? 0 : Idx + 1; 2063fa3d789dSPierre van Houtryve SearchIdx != EndIdx; ++SearchIdx) { 2064fa3d789dSPierre van Houtryve std::vector<unsigned> Intersection; 2065fa3d789dSPierre van Houtryve std::set_intersection( 2066fa3d789dSPierre van Houtryve RegUnitSets[Idx].Units.begin(), RegUnitSets[Idx].Units.end(), 2067fa3d789dSPierre van Houtryve RegUnitSets[SearchIdx].Units.begin(), 2068fa3d789dSPierre van Houtryve RegUnitSets[SearchIdx].Units.end(), std::back_inserter(Intersection)); 2069fa3d789dSPierre van Houtryve if (Intersection.empty()) 2070fa3d789dSPierre van Houtryve continue; 2071fa3d789dSPierre van Houtryve 2072fa3d789dSPierre van Houtryve RegUnitSet RUSet(RegUnitSets[Idx].Name + "_with_" + 2073fa3d789dSPierre van Houtryve RegUnitSets[SearchIdx].Name); 2074fa3d789dSPierre van Houtryve std::set_union(RegUnitSets[Idx].Units.begin(), 2075fa3d789dSPierre van Houtryve RegUnitSets[Idx].Units.end(), 2076fa3d789dSPierre van Houtryve RegUnitSets[SearchIdx].Units.begin(), 2077fa3d789dSPierre van Houtryve RegUnitSets[SearchIdx].Units.end(), 2078fa3d789dSPierre van Houtryve std::inserter(RUSet.Units, RUSet.Units.begin())); 2079fa3d789dSPierre van Houtryve 2080fa3d789dSPierre van Houtryve // Find an existing RegUnitSet, or add the union to the unique sets. 2081fa3d789dSPierre van Houtryve if (findRegUnitSet(RegUnitSets, RUSet) == RegUnitSets.end()) { 2082fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "UnitSet " << RegUnitSets.size() << " " 2083fa3d789dSPierre van Houtryve << RUSet.Name << ":"; 2084fa3d789dSPierre van Houtryve for (auto &U 2085fa3d789dSPierre van Houtryve : RUSet.Units) printRegUnitName(U); 2086fa3d789dSPierre van Houtryve dbgs() << "\n";); 2087fa3d789dSPierre van Houtryve RegUnitSets.push_back(std::move(RUSet)); 2088fa3d789dSPierre van Houtryve } 2089fa3d789dSPierre van Houtryve } 2090fa3d789dSPierre van Houtryve } 2091fa3d789dSPierre van Houtryve 2092fa3d789dSPierre van Houtryve // Iteratively prune unit sets after inferring supersets. 2093fa3d789dSPierre van Houtryve pruneUnitSets(); 2094fa3d789dSPierre van Houtryve 2095fa3d789dSPierre van Houtryve LLVM_DEBUG( 2096fa3d789dSPierre van Houtryve dbgs() << "\n"; for (unsigned USIdx = 0, USEnd = RegUnitSets.size(); 2097fa3d789dSPierre van Houtryve USIdx < USEnd; ++USIdx) { 2098fa3d789dSPierre van Houtryve dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":"; 2099fa3d789dSPierre van Houtryve for (auto &U : RegUnitSets[USIdx].Units) 2100fa3d789dSPierre van Houtryve printRegUnitName(U); 2101fa3d789dSPierre van Houtryve dbgs() << "\n"; 2102fa3d789dSPierre van Houtryve }); 2103fa3d789dSPierre van Houtryve 2104fa3d789dSPierre van Houtryve // For each register class, list the UnitSets that are supersets. 2105fa3d789dSPierre van Houtryve RegClassUnitSets.resize(RegClasses.size()); 2106fa3d789dSPierre van Houtryve int RCIdx = -1; 2107fa3d789dSPierre van Houtryve for (auto &RC : RegClasses) { 2108fa3d789dSPierre van Houtryve ++RCIdx; 2109fa3d789dSPierre van Houtryve if (!RC.Allocatable) 2110fa3d789dSPierre van Houtryve continue; 2111fa3d789dSPierre van Houtryve 2112fa3d789dSPierre van Houtryve // Recompute the sorted list of units in this class. 2113fa3d789dSPierre van Houtryve std::vector<unsigned> RCRegUnits; 2114fa3d789dSPierre van Houtryve RC.buildRegUnitSet(*this, RCRegUnits); 2115fa3d789dSPierre van Houtryve 2116fa3d789dSPierre van Houtryve // Don't increase pressure for unallocatable regclasses. 2117fa3d789dSPierre van Houtryve if (RCRegUnits.empty()) 2118fa3d789dSPierre van Houtryve continue; 2119fa3d789dSPierre van Houtryve 2120fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "RC " << RC.getName() << " Units:\n"; 2121fa3d789dSPierre van Houtryve for (auto U 2122fa3d789dSPierre van Houtryve : RCRegUnits) printRegUnitName(U); 2123fa3d789dSPierre van Houtryve dbgs() << "\n UnitSetIDs:"); 2124fa3d789dSPierre van Houtryve 2125fa3d789dSPierre van Houtryve // Find all supersets. 2126fa3d789dSPierre van Houtryve for (unsigned USIdx = 0, USEnd = RegUnitSets.size(); USIdx != USEnd; 2127fa3d789dSPierre van Houtryve ++USIdx) { 2128fa3d789dSPierre van Houtryve if (isRegUnitSubSet(RCRegUnits, RegUnitSets[USIdx].Units)) { 2129fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << " " << USIdx); 2130fa3d789dSPierre van Houtryve RegClassUnitSets[RCIdx].push_back(USIdx); 2131fa3d789dSPierre van Houtryve } 2132fa3d789dSPierre van Houtryve } 2133fa3d789dSPierre van Houtryve LLVM_DEBUG(dbgs() << "\n"); 2134fa3d789dSPierre van Houtryve assert((!RegClassUnitSets[RCIdx].empty() || !RC.GeneratePressureSet) && 2135fa3d789dSPierre van Houtryve "missing unit set for regclass"); 2136fa3d789dSPierre van Houtryve } 2137fa3d789dSPierre van Houtryve 2138fa3d789dSPierre van Houtryve // For each register unit, ensure that we have the list of UnitSets that 2139fa3d789dSPierre van Houtryve // contain the unit. Normally, this matches an existing list of UnitSets for a 2140fa3d789dSPierre van Houtryve // register class. If not, we create a new entry in RegClassUnitSets as a 2141fa3d789dSPierre van Houtryve // "fake" register class. 2142fa3d789dSPierre van Houtryve for (unsigned UnitIdx = 0, UnitEnd = NumNativeRegUnits; UnitIdx < UnitEnd; 2143fa3d789dSPierre van Houtryve ++UnitIdx) { 2144fa3d789dSPierre van Houtryve std::vector<unsigned> RUSets; 2145fa3d789dSPierre van Houtryve for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) { 2146fa3d789dSPierre van Houtryve if (is_contained(RegUnitSets[i].Units, UnitIdx)) 2147fa3d789dSPierre van Houtryve RUSets.push_back(i); 2148fa3d789dSPierre van Houtryve } 2149fa3d789dSPierre van Houtryve unsigned RCUnitSetsIdx = 0; 2150fa3d789dSPierre van Houtryve for (unsigned e = RegClassUnitSets.size(); RCUnitSetsIdx != e; 2151fa3d789dSPierre van Houtryve ++RCUnitSetsIdx) { 2152fa3d789dSPierre van Houtryve if (RegClassUnitSets[RCUnitSetsIdx] == RUSets) { 2153fa3d789dSPierre van Houtryve break; 2154fa3d789dSPierre van Houtryve } 2155fa3d789dSPierre van Houtryve } 2156fa3d789dSPierre van Houtryve RegUnits[UnitIdx].RegClassUnitSetsIdx = RCUnitSetsIdx; 2157fa3d789dSPierre van Houtryve if (RCUnitSetsIdx == RegClassUnitSets.size()) { 2158fa3d789dSPierre van Houtryve // Create a new list of UnitSets as a "fake" register class. 2159fa3d789dSPierre van Houtryve RegClassUnitSets.push_back(std::move(RUSets)); 2160fa3d789dSPierre van Houtryve } 2161fa3d789dSPierre van Houtryve } 2162fa3d789dSPierre van Houtryve } 2163fa3d789dSPierre van Houtryve 2164fa3d789dSPierre van Houtryve void CodeGenRegBank::computeRegUnitLaneMasks() { 2165fa3d789dSPierre van Houtryve for (auto &Register : Registers) { 2166fa3d789dSPierre van Houtryve // Create an initial lane mask for all register units. 2167fa3d789dSPierre van Houtryve const auto &RegUnits = Register.getRegUnits(); 2168fa3d789dSPierre van Houtryve CodeGenRegister::RegUnitLaneMaskList RegUnitLaneMasks( 2169fa3d789dSPierre van Houtryve RegUnits.count(), LaneBitmask::getAll()); 2170fa3d789dSPierre van Houtryve // Iterate through SubRegisters. 2171fa3d789dSPierre van Houtryve typedef CodeGenRegister::SubRegMap SubRegMap; 2172fa3d789dSPierre van Houtryve const SubRegMap &SubRegs = Register.getSubRegs(); 2173fa3d789dSPierre van Houtryve for (auto S : SubRegs) { 2174fa3d789dSPierre van Houtryve CodeGenRegister *SubReg = S.second; 2175fa3d789dSPierre van Houtryve // Ignore non-leaf subregisters, their lane masks are fully covered by 2176fa3d789dSPierre van Houtryve // the leaf subregisters anyway. 2177fa3d789dSPierre van Houtryve if (!SubReg->getSubRegs().empty()) 2178fa3d789dSPierre van Houtryve continue; 2179fa3d789dSPierre van Houtryve CodeGenSubRegIndex *SubRegIndex = S.first; 2180fa3d789dSPierre van Houtryve const CodeGenRegister *SubRegister = S.second; 2181fa3d789dSPierre van Houtryve LaneBitmask LaneMask = SubRegIndex->LaneMask; 2182fa3d789dSPierre van Houtryve // Distribute LaneMask to Register Units touched. 2183fa3d789dSPierre van Houtryve for (unsigned SUI : SubRegister->getRegUnits()) { 2184fa3d789dSPierre van Houtryve bool Found = false; 2185fa3d789dSPierre van Houtryve unsigned u = 0; 2186fa3d789dSPierre van Houtryve for (unsigned RU : RegUnits) { 2187fa3d789dSPierre van Houtryve if (SUI == RU) { 2188fa3d789dSPierre van Houtryve RegUnitLaneMasks[u] &= LaneMask; 2189fa3d789dSPierre van Houtryve assert(!Found); 2190fa3d789dSPierre van Houtryve Found = true; 2191fa3d789dSPierre van Houtryve } 2192fa3d789dSPierre van Houtryve ++u; 2193fa3d789dSPierre van Houtryve } 2194fa3d789dSPierre van Houtryve (void)Found; 2195fa3d789dSPierre van Houtryve assert(Found); 2196fa3d789dSPierre van Houtryve } 2197fa3d789dSPierre van Houtryve } 2198fa3d789dSPierre van Houtryve Register.setRegUnitLaneMasks(RegUnitLaneMasks); 2199fa3d789dSPierre van Houtryve } 2200fa3d789dSPierre van Houtryve } 2201fa3d789dSPierre van Houtryve 2202fa3d789dSPierre van Houtryve void CodeGenRegBank::computeDerivedInfo() { 2203fa3d789dSPierre van Houtryve computeComposites(); 2204fa3d789dSPierre van Houtryve computeSubRegLaneMasks(); 2205fa3d789dSPierre van Houtryve 2206fa3d789dSPierre van Houtryve // Compute a weight for each register unit created during getSubRegs. 2207fa3d789dSPierre van Houtryve // This may create adopted register units (with unit # >= NumNativeRegUnits). 2208fa3d789dSPierre van Houtryve computeRegUnitWeights(); 2209fa3d789dSPierre van Houtryve 2210fa3d789dSPierre van Houtryve // Compute a unique set of RegUnitSets. One for each RegClass and inferred 2211fa3d789dSPierre van Houtryve // supersets for the union of overlapping sets. 2212fa3d789dSPierre van Houtryve computeRegUnitSets(); 2213fa3d789dSPierre van Houtryve 2214fa3d789dSPierre van Houtryve computeRegUnitLaneMasks(); 2215fa3d789dSPierre van Houtryve 2216fa3d789dSPierre van Houtryve // Compute register class HasDisjunctSubRegs/CoveredBySubRegs flag. 2217fa3d789dSPierre van Houtryve for (CodeGenRegisterClass &RC : RegClasses) { 2218fa3d789dSPierre van Houtryve RC.HasDisjunctSubRegs = false; 2219fa3d789dSPierre van Houtryve RC.CoveredBySubRegs = true; 2220fa3d789dSPierre van Houtryve for (const CodeGenRegister *Reg : RC.getMembers()) { 2221fa3d789dSPierre van Houtryve RC.HasDisjunctSubRegs |= Reg->HasDisjunctSubRegs; 2222fa3d789dSPierre van Houtryve RC.CoveredBySubRegs &= Reg->CoveredBySubRegs; 2223fa3d789dSPierre van Houtryve } 2224fa3d789dSPierre van Houtryve } 2225fa3d789dSPierre van Houtryve 2226fa3d789dSPierre van Houtryve // Get the weight of each set. 2227fa3d789dSPierre van Houtryve for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) 2228fa3d789dSPierre van Houtryve RegUnitSets[Idx].Weight = getRegUnitSetWeight(RegUnitSets[Idx].Units); 2229fa3d789dSPierre van Houtryve 2230fa3d789dSPierre van Houtryve // Find the order of each set. 2231fa3d789dSPierre van Houtryve RegUnitSetOrder.reserve(RegUnitSets.size()); 2232fa3d789dSPierre van Houtryve for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) 2233fa3d789dSPierre van Houtryve RegUnitSetOrder.push_back(Idx); 2234fa3d789dSPierre van Houtryve 2235fa3d789dSPierre van Houtryve llvm::stable_sort(RegUnitSetOrder, [this](unsigned ID1, unsigned ID2) { 2236fa3d789dSPierre van Houtryve return getRegPressureSet(ID1).Units.size() < 2237fa3d789dSPierre van Houtryve getRegPressureSet(ID2).Units.size(); 2238fa3d789dSPierre van Houtryve }); 2239fa3d789dSPierre van Houtryve for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) { 2240fa3d789dSPierre van Houtryve RegUnitSets[RegUnitSetOrder[Idx]].Order = Idx; 2241fa3d789dSPierre van Houtryve } 2242fa3d789dSPierre van Houtryve } 2243fa3d789dSPierre van Houtryve 2244fa3d789dSPierre van Houtryve // 2245fa3d789dSPierre van Houtryve // Synthesize missing register class intersections. 2246fa3d789dSPierre van Houtryve // 2247fa3d789dSPierre van Houtryve // Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X) 2248fa3d789dSPierre van Houtryve // returns a maximal register class for all X. 2249fa3d789dSPierre van Houtryve // 2250fa3d789dSPierre van Houtryve void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) { 2251fa3d789dSPierre van Houtryve assert(!RegClasses.empty()); 2252fa3d789dSPierre van Houtryve // Stash the iterator to the last element so that this loop doesn't visit 2253fa3d789dSPierre van Houtryve // elements added by the getOrCreateSubClass call within it. 2254fa3d789dSPierre van Houtryve for (auto I = RegClasses.begin(), E = std::prev(RegClasses.end()); 2255fa3d789dSPierre van Houtryve I != std::next(E); ++I) { 2256fa3d789dSPierre van Houtryve CodeGenRegisterClass *RC1 = RC; 2257fa3d789dSPierre van Houtryve CodeGenRegisterClass *RC2 = &*I; 2258fa3d789dSPierre van Houtryve if (RC1 == RC2) 2259fa3d789dSPierre van Houtryve continue; 2260fa3d789dSPierre van Houtryve 2261fa3d789dSPierre van Houtryve // Compute the set intersection of RC1 and RC2. 2262fa3d789dSPierre van Houtryve const CodeGenRegister::Vec &Memb1 = RC1->getMembers(); 2263fa3d789dSPierre van Houtryve const CodeGenRegister::Vec &Memb2 = RC2->getMembers(); 2264fa3d789dSPierre van Houtryve CodeGenRegister::Vec Intersection; 2265fa3d789dSPierre van Houtryve std::set_intersection(Memb1.begin(), Memb1.end(), Memb2.begin(), 2266fa3d789dSPierre van Houtryve Memb2.end(), 2267fa3d789dSPierre van Houtryve std::inserter(Intersection, Intersection.begin()), 2268fa3d789dSPierre van Houtryve deref<std::less<>>()); 2269fa3d789dSPierre van Houtryve 2270fa3d789dSPierre van Houtryve // Skip disjoint class pairs. 2271fa3d789dSPierre van Houtryve if (Intersection.empty()) 2272fa3d789dSPierre van Houtryve continue; 2273fa3d789dSPierre van Houtryve 2274fa3d789dSPierre van Houtryve // If RC1 and RC2 have different spill sizes or alignments, use the 2275fa3d789dSPierre van Houtryve // stricter one for sub-classing. If they are equal, prefer RC1. 2276fa3d789dSPierre van Houtryve if (RC2->RSI.hasStricterSpillThan(RC1->RSI)) 2277fa3d789dSPierre van Houtryve std::swap(RC1, RC2); 2278fa3d789dSPierre van Houtryve 2279fa3d789dSPierre van Houtryve getOrCreateSubClass(RC1, &Intersection, 2280fa3d789dSPierre van Houtryve RC1->getName() + "_and_" + RC2->getName()); 2281fa3d789dSPierre van Houtryve } 2282fa3d789dSPierre van Houtryve } 2283fa3d789dSPierre van Houtryve 2284fa3d789dSPierre van Houtryve // 2285fa3d789dSPierre van Houtryve // Synthesize missing sub-classes for getSubClassWithSubReg(). 2286fa3d789dSPierre van Houtryve // 2287fa3d789dSPierre van Houtryve // Make sure that the set of registers in RC with a given SubIdx sub-register 2288fa3d789dSPierre van Houtryve // form a register class. Update RC->SubClassWithSubReg. 2289fa3d789dSPierre van Houtryve // 2290fa3d789dSPierre van Houtryve void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) { 2291fa3d789dSPierre van Houtryve // Map SubRegIndex to set of registers in RC supporting that SubRegIndex. 2292fa3d789dSPierre van Houtryve typedef std::map<const CodeGenSubRegIndex *, CodeGenRegister::Vec, 2293fa3d789dSPierre van Houtryve deref<std::less<>>> 2294fa3d789dSPierre van Houtryve SubReg2SetMap; 2295fa3d789dSPierre van Houtryve 2296fa3d789dSPierre van Houtryve // Compute the set of registers supporting each SubRegIndex. 2297fa3d789dSPierre van Houtryve SubReg2SetMap SRSets; 2298fa3d789dSPierre van Houtryve for (const auto R : RC->getMembers()) { 2299fa3d789dSPierre van Houtryve if (R->Artificial) 2300fa3d789dSPierre van Houtryve continue; 2301fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap &SRM = R->getSubRegs(); 2302ae0ab248SSander de Smalen for (auto I : SRM) 2303fa3d789dSPierre van Houtryve SRSets[I.first].push_back(R); 2304fa3d789dSPierre van Houtryve } 2305fa3d789dSPierre van Houtryve 2306fa3d789dSPierre van Houtryve for (auto I : SRSets) 2307fa3d789dSPierre van Houtryve sortAndUniqueRegisters(I.second); 2308fa3d789dSPierre van Houtryve 2309fa3d789dSPierre van Houtryve // Find matching classes for all SRSets entries. Iterate in SubRegIndex 2310fa3d789dSPierre van Houtryve // numerical order to visit synthetic indices last. 2311fa3d789dSPierre van Houtryve for (const auto &SubIdx : SubRegIndices) { 2312fa3d789dSPierre van Houtryve SubReg2SetMap::const_iterator I = SRSets.find(&SubIdx); 2313fa3d789dSPierre van Houtryve // Unsupported SubRegIndex. Skip it. 2314fa3d789dSPierre van Houtryve if (I == SRSets.end()) 2315fa3d789dSPierre van Houtryve continue; 2316fa3d789dSPierre van Houtryve // In most cases, all RC registers support the SubRegIndex. 2317fa3d789dSPierre van Houtryve if (I->second.size() == RC->getMembers().size()) { 2318fa3d789dSPierre van Houtryve RC->setSubClassWithSubReg(&SubIdx, RC); 2319fa3d789dSPierre van Houtryve continue; 2320fa3d789dSPierre van Houtryve } 2321ae0ab248SSander de Smalen if (SubIdx.Artificial) 2322ae0ab248SSander de Smalen continue; 2323fa3d789dSPierre van Houtryve // This is a real subset. See if we have a matching class. 2324fa3d789dSPierre van Houtryve CodeGenRegisterClass *SubRC = getOrCreateSubClass( 2325fa3d789dSPierre van Houtryve RC, &I->second, RC->getName() + "_with_" + I->first->getName()); 2326fa3d789dSPierre van Houtryve RC->setSubClassWithSubReg(&SubIdx, SubRC); 2327fa3d789dSPierre van Houtryve } 2328fa3d789dSPierre van Houtryve } 2329fa3d789dSPierre van Houtryve 2330fa3d789dSPierre van Houtryve // 2331fa3d789dSPierre van Houtryve // Synthesize missing sub-classes of RC for getMatchingSuperRegClass(). 2332fa3d789dSPierre van Houtryve // 2333fa3d789dSPierre van Houtryve // Create sub-classes of RC such that getMatchingSuperRegClass(RC, SubIdx, X) 2334fa3d789dSPierre van Houtryve // has a maximal result for any SubIdx and any X >= FirstSubRegRC. 2335fa3d789dSPierre van Houtryve // 2336fa3d789dSPierre van Houtryve 2337fa3d789dSPierre van Houtryve void CodeGenRegBank::inferMatchingSuperRegClass( 2338fa3d789dSPierre van Houtryve CodeGenRegisterClass *RC, 2339fa3d789dSPierre van Houtryve std::list<CodeGenRegisterClass>::iterator FirstSubRegRC) { 2340fa3d789dSPierre van Houtryve DenseMap<const CodeGenRegister *, std::vector<const CodeGenRegister *>> 2341fa3d789dSPierre van Houtryve SubToSuperRegs; 2342fa3d789dSPierre van Houtryve BitVector TopoSigs(getNumTopoSigs()); 2343fa3d789dSPierre van Houtryve 2344fa3d789dSPierre van Houtryve // Iterate in SubRegIndex numerical order to visit synthetic indices last. 2345fa3d789dSPierre van Houtryve for (auto &SubIdx : SubRegIndices) { 2346fa3d789dSPierre van Houtryve // Skip indexes that aren't fully supported by RC's registers. This was 2347fa3d789dSPierre van Houtryve // computed by inferSubClassWithSubReg() above which should have been 2348fa3d789dSPierre van Houtryve // called first. 2349fa3d789dSPierre van Houtryve if (RC->getSubClassWithSubReg(&SubIdx) != RC) 2350fa3d789dSPierre van Houtryve continue; 2351fa3d789dSPierre van Houtryve 2352fa3d789dSPierre van Houtryve // Build list of (Super, Sub) pairs for this SubIdx. 2353fa3d789dSPierre van Houtryve SubToSuperRegs.clear(); 2354fa3d789dSPierre van Houtryve TopoSigs.reset(); 2355fa3d789dSPierre van Houtryve for (const auto Super : RC->getMembers()) { 2356fa3d789dSPierre van Houtryve const CodeGenRegister *Sub = Super->getSubRegs().find(&SubIdx)->second; 2357fa3d789dSPierre van Houtryve assert(Sub && "Missing sub-register"); 2358fa3d789dSPierre van Houtryve SubToSuperRegs[Sub].push_back(Super); 2359fa3d789dSPierre van Houtryve TopoSigs.set(Sub->getTopoSig()); 2360fa3d789dSPierre van Houtryve } 2361fa3d789dSPierre van Houtryve 2362fa3d789dSPierre van Houtryve // Iterate over sub-register class candidates. Ignore classes created by 2363fa3d789dSPierre van Houtryve // this loop. They will never be useful. 2364fa3d789dSPierre van Houtryve // Store an iterator to the last element (not end) so that this loop doesn't 2365fa3d789dSPierre van Houtryve // visit newly inserted elements. 2366fa3d789dSPierre van Houtryve assert(!RegClasses.empty()); 2367fa3d789dSPierre van Houtryve for (auto I = FirstSubRegRC, E = std::prev(RegClasses.end()); 2368fa3d789dSPierre van Houtryve I != std::next(E); ++I) { 2369fa3d789dSPierre van Houtryve CodeGenRegisterClass &SubRC = *I; 2370fa3d789dSPierre van Houtryve if (SubRC.Artificial) 2371fa3d789dSPierre van Houtryve continue; 2372fa3d789dSPierre van Houtryve // Topological shortcut: SubRC members have the wrong shape. 2373fa3d789dSPierre van Houtryve if (!TopoSigs.anyCommon(SubRC.getTopoSigs())) 2374fa3d789dSPierre van Houtryve continue; 2375fa3d789dSPierre van Houtryve // Compute the subset of RC that maps into SubRC. 2376fa3d789dSPierre van Houtryve CodeGenRegister::Vec SubSetVec; 2377fa3d789dSPierre van Houtryve for (const CodeGenRegister *R : SubRC.getMembers()) { 2378fa3d789dSPierre van Houtryve auto It = SubToSuperRegs.find(R); 2379fa3d789dSPierre van Houtryve if (It != SubToSuperRegs.end()) { 2380fa3d789dSPierre van Houtryve const std::vector<const CodeGenRegister *> &SuperRegs = It->second; 2381fa3d789dSPierre van Houtryve SubSetVec.insert(SubSetVec.end(), SuperRegs.begin(), SuperRegs.end()); 2382fa3d789dSPierre van Houtryve } 2383fa3d789dSPierre van Houtryve } 2384fa3d789dSPierre van Houtryve 2385fa3d789dSPierre van Houtryve if (SubSetVec.empty()) 2386fa3d789dSPierre van Houtryve continue; 2387fa3d789dSPierre van Houtryve 2388fa3d789dSPierre van Houtryve // RC injects completely into SubRC. 2389fa3d789dSPierre van Houtryve sortAndUniqueRegisters(SubSetVec); 2390fa3d789dSPierre van Houtryve if (SubSetVec.size() == RC->getMembers().size()) { 2391fa3d789dSPierre van Houtryve SubRC.addSuperRegClass(&SubIdx, RC); 2392fa3d789dSPierre van Houtryve continue; 2393fa3d789dSPierre van Houtryve } 2394fa3d789dSPierre van Houtryve 2395fa3d789dSPierre van Houtryve // Only a subset of RC maps into SubRC. Make sure it is represented by a 2396fa3d789dSPierre van Houtryve // class. 2397fa3d789dSPierre van Houtryve getOrCreateSubClass(RC, &SubSetVec, 2398fa3d789dSPierre van Houtryve RC->getName() + "_with_" + SubIdx.getName() + "_in_" + 2399fa3d789dSPierre van Houtryve SubRC.getName()); 2400fa3d789dSPierre van Houtryve } 2401fa3d789dSPierre van Houtryve } 2402fa3d789dSPierre van Houtryve } 2403fa3d789dSPierre van Houtryve 2404fa3d789dSPierre van Houtryve // 2405fa3d789dSPierre van Houtryve // Infer missing register classes. 2406fa3d789dSPierre van Houtryve // 2407fa3d789dSPierre van Houtryve void CodeGenRegBank::computeInferredRegisterClasses() { 2408fa3d789dSPierre van Houtryve assert(!RegClasses.empty()); 2409fa3d789dSPierre van Houtryve // When this function is called, the register classes have not been sorted 2410fa3d789dSPierre van Houtryve // and assigned EnumValues yet. That means getSubClasses(), 2411fa3d789dSPierre van Houtryve // getSuperClasses(), and hasSubClass() functions are defunct. 2412fa3d789dSPierre van Houtryve 2413fa3d789dSPierre van Houtryve // Use one-before-the-end so it doesn't move forward when new elements are 2414fa3d789dSPierre van Houtryve // added. 2415fa3d789dSPierre van Houtryve auto FirstNewRC = std::prev(RegClasses.end()); 2416fa3d789dSPierre van Houtryve 2417fa3d789dSPierre van Houtryve // Visit all register classes, including the ones being added by the loop. 2418fa3d789dSPierre van Houtryve // Watch out for iterator invalidation here. 2419fa3d789dSPierre van Houtryve for (auto I = RegClasses.begin(), E = RegClasses.end(); I != E; ++I) { 2420fa3d789dSPierre van Houtryve CodeGenRegisterClass *RC = &*I; 2421fa3d789dSPierre van Houtryve if (RC->Artificial) 2422fa3d789dSPierre van Houtryve continue; 2423fa3d789dSPierre van Houtryve 2424fa3d789dSPierre van Houtryve // Synthesize answers for getSubClassWithSubReg(). 2425fa3d789dSPierre van Houtryve inferSubClassWithSubReg(RC); 2426fa3d789dSPierre van Houtryve 2427fa3d789dSPierre van Houtryve // Synthesize answers for getCommonSubClass(). 2428fa3d789dSPierre van Houtryve inferCommonSubClass(RC); 2429fa3d789dSPierre van Houtryve 2430fa3d789dSPierre van Houtryve // Synthesize answers for getMatchingSuperRegClass(). 2431fa3d789dSPierre van Houtryve inferMatchingSuperRegClass(RC); 2432fa3d789dSPierre van Houtryve 2433fa3d789dSPierre van Houtryve // New register classes are created while this loop is running, and we need 2434fa3d789dSPierre van Houtryve // to visit all of them. I particular, inferMatchingSuperRegClass needs 2435fa3d789dSPierre van Houtryve // to match old super-register classes with sub-register classes created 2436fa3d789dSPierre van Houtryve // after inferMatchingSuperRegClass was called. At this point, 2437fa3d789dSPierre van Houtryve // inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC = 2438fa3d789dSPierre van Houtryve // [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci]. 2439fa3d789dSPierre van Houtryve if (I == FirstNewRC) { 2440fa3d789dSPierre van Houtryve auto NextNewRC = std::prev(RegClasses.end()); 2441fa3d789dSPierre van Houtryve for (auto I2 = RegClasses.begin(), E2 = std::next(FirstNewRC); I2 != E2; 2442fa3d789dSPierre van Houtryve ++I2) 2443fa3d789dSPierre van Houtryve inferMatchingSuperRegClass(&*I2, E2); 2444fa3d789dSPierre van Houtryve FirstNewRC = NextNewRC; 2445fa3d789dSPierre van Houtryve } 2446fa3d789dSPierre van Houtryve } 2447fa3d789dSPierre van Houtryve } 2448fa3d789dSPierre van Houtryve 2449fa3d789dSPierre van Houtryve /// getRegisterClassForRegister - Find the register class that contains the 2450fa3d789dSPierre van Houtryve /// specified physical register. If the register is not in a register class, 2451fa3d789dSPierre van Houtryve /// return null. If the register is in multiple classes, and the classes have a 2452fa3d789dSPierre van Houtryve /// superset-subset relationship and the same set of types, return the 2453fa3d789dSPierre van Houtryve /// superclass. Otherwise return null. 24547c6592f5SRahul Joshi const CodeGenRegisterClass * 24557c6592f5SRahul Joshi CodeGenRegBank::getRegClassForRegister(const Record *R) { 2456fa3d789dSPierre van Houtryve const CodeGenRegister *Reg = getReg(R); 2457fa3d789dSPierre van Houtryve const CodeGenRegisterClass *FoundRC = nullptr; 2458fa3d789dSPierre van Houtryve for (const auto &RC : getRegClasses()) { 2459fa3d789dSPierre van Houtryve if (!RC.contains(Reg)) 2460fa3d789dSPierre van Houtryve continue; 2461fa3d789dSPierre van Houtryve 2462fa3d789dSPierre van Houtryve // If this is the first class that contains the register, 2463fa3d789dSPierre van Houtryve // make a note of it and go on to the next class. 2464fa3d789dSPierre van Houtryve if (!FoundRC) { 2465fa3d789dSPierre van Houtryve FoundRC = &RC; 2466fa3d789dSPierre van Houtryve continue; 2467fa3d789dSPierre van Houtryve } 2468fa3d789dSPierre van Houtryve 2469fa3d789dSPierre van Houtryve // If a register's classes have different types, return null. 2470fa3d789dSPierre van Houtryve if (RC.getValueTypes() != FoundRC->getValueTypes()) 2471fa3d789dSPierre van Houtryve return nullptr; 2472fa3d789dSPierre van Houtryve 2473fa3d789dSPierre van Houtryve // Check to see if the previously found class that contains 2474fa3d789dSPierre van Houtryve // the register is a subclass of the current class. If so, 2475fa3d789dSPierre van Houtryve // prefer the superclass. 2476fa3d789dSPierre van Houtryve if (RC.hasSubClass(FoundRC)) { 2477fa3d789dSPierre van Houtryve FoundRC = &RC; 2478fa3d789dSPierre van Houtryve continue; 2479fa3d789dSPierre van Houtryve } 2480fa3d789dSPierre van Houtryve 2481fa3d789dSPierre van Houtryve // Check to see if the previously found class that contains 2482fa3d789dSPierre van Houtryve // the register is a superclass of the current class. If so, 2483fa3d789dSPierre van Houtryve // prefer the superclass. 2484fa3d789dSPierre van Houtryve if (FoundRC->hasSubClass(&RC)) 2485fa3d789dSPierre van Houtryve continue; 2486fa3d789dSPierre van Houtryve 2487fa3d789dSPierre van Houtryve // Multiple classes, and neither is a superclass of the other. 2488fa3d789dSPierre van Houtryve // Return null. 2489fa3d789dSPierre van Houtryve return nullptr; 2490fa3d789dSPierre van Houtryve } 2491fa3d789dSPierre van Houtryve return FoundRC; 2492fa3d789dSPierre van Houtryve } 2493fa3d789dSPierre van Houtryve 2494fa3d789dSPierre van Houtryve const CodeGenRegisterClass * 24957c6592f5SRahul Joshi CodeGenRegBank::getMinimalPhysRegClass(const Record *RegRecord, 2496fa3d789dSPierre van Houtryve ValueTypeByHwMode *VT) { 2497fa3d789dSPierre van Houtryve const CodeGenRegister *Reg = getReg(RegRecord); 2498fa3d789dSPierre van Houtryve const CodeGenRegisterClass *BestRC = nullptr; 2499fa3d789dSPierre van Houtryve for (const auto &RC : getRegClasses()) { 2500fa3d789dSPierre van Houtryve if ((!VT || RC.hasType(*VT)) && RC.contains(Reg) && 2501fa3d789dSPierre van Houtryve (!BestRC || BestRC->hasSubClass(&RC))) 2502fa3d789dSPierre van Houtryve BestRC = &RC; 2503fa3d789dSPierre van Houtryve } 2504fa3d789dSPierre van Houtryve 2505fa3d789dSPierre van Houtryve assert(BestRC && "Couldn't find the register class"); 2506fa3d789dSPierre van Houtryve return BestRC; 2507fa3d789dSPierre van Houtryve } 2508fa3d789dSPierre van Houtryve 250916510149SRahul Joshi BitVector 251016510149SRahul Joshi CodeGenRegBank::computeCoveredRegisters(ArrayRef<const Record *> Regs) { 2511fa3d789dSPierre van Houtryve SetVector<const CodeGenRegister *> Set; 2512fa3d789dSPierre van Houtryve 2513fa3d789dSPierre van Houtryve // First add Regs with all sub-registers. 2514fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Regs.size(); i != e; ++i) { 2515fa3d789dSPierre van Houtryve CodeGenRegister *Reg = getReg(Regs[i]); 2516fa3d789dSPierre van Houtryve if (Set.insert(Reg)) 2517fa3d789dSPierre van Houtryve // Reg is new, add all sub-registers. 2518fa3d789dSPierre van Houtryve // The pre-ordering is not important here. 2519fa3d789dSPierre van Houtryve Reg->addSubRegsPreOrder(Set, *this); 2520fa3d789dSPierre van Houtryve } 2521fa3d789dSPierre van Houtryve 2522fa3d789dSPierre van Houtryve // Second, find all super-registers that are completely covered by the set. 2523fa3d789dSPierre van Houtryve for (unsigned i = 0; i != Set.size(); ++i) { 2524fa3d789dSPierre van Houtryve const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs(); 2525fa3d789dSPierre van Houtryve for (unsigned j = 0, e = SR.size(); j != e; ++j) { 2526fa3d789dSPierre van Houtryve const CodeGenRegister *Super = SR[j]; 2527fa3d789dSPierre van Houtryve if (!Super->CoveredBySubRegs || Set.count(Super)) 2528fa3d789dSPierre van Houtryve continue; 2529fa3d789dSPierre van Houtryve // This new super-register is covered by its sub-registers. 2530fa3d789dSPierre van Houtryve bool AllSubsInSet = true; 2531fa3d789dSPierre van Houtryve const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs(); 2532fa3d789dSPierre van Houtryve for (auto I : SRM) 2533fa3d789dSPierre van Houtryve if (!Set.count(I.second)) { 2534fa3d789dSPierre van Houtryve AllSubsInSet = false; 2535fa3d789dSPierre van Houtryve break; 2536fa3d789dSPierre van Houtryve } 2537fa3d789dSPierre van Houtryve // All sub-registers in Set, add Super as well. 2538fa3d789dSPierre van Houtryve // We will visit Super later to recheck its super-registers. 2539fa3d789dSPierre van Houtryve if (AllSubsInSet) 2540fa3d789dSPierre van Houtryve Set.insert(Super); 2541fa3d789dSPierre van Houtryve } 2542fa3d789dSPierre van Houtryve } 2543fa3d789dSPierre van Houtryve 2544fa3d789dSPierre van Houtryve // Convert to BitVector. 2545fa3d789dSPierre van Houtryve BitVector BV(Registers.size() + 1); 2546fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Set.size(); i != e; ++i) 2547fa3d789dSPierre van Houtryve BV.set(Set[i]->EnumValue); 2548fa3d789dSPierre van Houtryve return BV; 2549fa3d789dSPierre van Houtryve } 2550fa3d789dSPierre van Houtryve 2551fa3d789dSPierre van Houtryve void CodeGenRegBank::printRegUnitName(unsigned Unit) const { 2552fa3d789dSPierre van Houtryve if (Unit < NumNativeRegUnits) 2553fa3d789dSPierre van Houtryve dbgs() << ' ' << RegUnits[Unit].Roots[0]->getName(); 2554fa3d789dSPierre van Houtryve else 2555fa3d789dSPierre van Houtryve dbgs() << " #" << Unit; 2556fa3d789dSPierre van Houtryve } 2557