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