1*0fca6ea1SDimitry Andric //===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===// 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 #ifndef LLVM_UTILS_TABLEGEN_CODEGENREGISTERS_H 15*0fca6ea1SDimitry Andric #define LLVM_UTILS_TABLEGEN_CODEGENREGISTERS_H 16*0fca6ea1SDimitry Andric 17*0fca6ea1SDimitry Andric #include "CodeGenHwModes.h" 18*0fca6ea1SDimitry Andric #include "InfoByHwMode.h" 19*0fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h" 20*0fca6ea1SDimitry Andric #include "llvm/ADT/BitVector.h" 21*0fca6ea1SDimitry Andric #include "llvm/ADT/DenseMap.h" 22*0fca6ea1SDimitry Andric #include "llvm/ADT/STLExtras.h" 23*0fca6ea1SDimitry Andric #include "llvm/ADT/SetVector.h" 24*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 25*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h" 26*0fca6ea1SDimitry Andric #include "llvm/ADT/SparseBitVector.h" 27*0fca6ea1SDimitry Andric #include "llvm/ADT/StringMap.h" 28*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h" 29*0fca6ea1SDimitry Andric #include "llvm/MC/LaneBitmask.h" 30*0fca6ea1SDimitry Andric #include "llvm/Support/ErrorHandling.h" 31*0fca6ea1SDimitry Andric #include "llvm/TableGen/Record.h" 32*0fca6ea1SDimitry Andric #include "llvm/TableGen/SetTheory.h" 33*0fca6ea1SDimitry Andric #include <cassert> 34*0fca6ea1SDimitry Andric #include <cstdint> 35*0fca6ea1SDimitry Andric #include <deque> 36*0fca6ea1SDimitry Andric #include <functional> 37*0fca6ea1SDimitry Andric #include <list> 38*0fca6ea1SDimitry Andric #include <map> 39*0fca6ea1SDimitry Andric #include <memory> 40*0fca6ea1SDimitry Andric #include <optional> 41*0fca6ea1SDimitry Andric #include <string> 42*0fca6ea1SDimitry Andric #include <utility> 43*0fca6ea1SDimitry Andric #include <vector> 44*0fca6ea1SDimitry Andric 45*0fca6ea1SDimitry Andric namespace llvm { 46*0fca6ea1SDimitry Andric 47*0fca6ea1SDimitry Andric class CodeGenRegBank; 48*0fca6ea1SDimitry Andric 49*0fca6ea1SDimitry Andric /// Used to encode a step in a register lane mask transformation. 50*0fca6ea1SDimitry Andric /// Mask the bits specified in Mask, then rotate them Rol bits to the left 51*0fca6ea1SDimitry Andric /// assuming a wraparound at 32bits. 52*0fca6ea1SDimitry Andric struct MaskRolPair { 53*0fca6ea1SDimitry Andric LaneBitmask Mask; 54*0fca6ea1SDimitry Andric uint8_t RotateLeft; 55*0fca6ea1SDimitry Andric 56*0fca6ea1SDimitry Andric bool operator==(const MaskRolPair Other) const { 57*0fca6ea1SDimitry Andric return Mask == Other.Mask && RotateLeft == Other.RotateLeft; 58*0fca6ea1SDimitry Andric } 59*0fca6ea1SDimitry Andric bool operator!=(const MaskRolPair Other) const { 60*0fca6ea1SDimitry Andric return Mask != Other.Mask || RotateLeft != Other.RotateLeft; 61*0fca6ea1SDimitry Andric } 62*0fca6ea1SDimitry Andric }; 63*0fca6ea1SDimitry Andric 64*0fca6ea1SDimitry Andric /// CodeGenSubRegIndex - Represents a sub-register index. 65*0fca6ea1SDimitry Andric class CodeGenSubRegIndex { 66*0fca6ea1SDimitry Andric Record *const TheDef; 67*0fca6ea1SDimitry Andric std::string Name; 68*0fca6ea1SDimitry Andric std::string Namespace; 69*0fca6ea1SDimitry Andric 70*0fca6ea1SDimitry Andric public: 71*0fca6ea1SDimitry Andric SubRegRangeByHwMode Range; 72*0fca6ea1SDimitry Andric const unsigned EnumValue; 73*0fca6ea1SDimitry Andric mutable LaneBitmask LaneMask; 74*0fca6ea1SDimitry Andric mutable SmallVector<MaskRolPair, 1> CompositionLaneMaskTransform; 75*0fca6ea1SDimitry Andric 76*0fca6ea1SDimitry Andric /// A list of subregister indexes concatenated resulting in this 77*0fca6ea1SDimitry Andric /// subregister index. This is the reverse of CodeGenRegBank::ConcatIdx. 78*0fca6ea1SDimitry Andric SmallVector<CodeGenSubRegIndex *, 4> ConcatenationOf; 79*0fca6ea1SDimitry Andric 80*0fca6ea1SDimitry Andric // Are all super-registers containing this SubRegIndex covered by their 81*0fca6ea1SDimitry Andric // sub-registers? 82*0fca6ea1SDimitry Andric bool AllSuperRegsCovered; 83*0fca6ea1SDimitry Andric // A subregister index is "artificial" if every subregister obtained 84*0fca6ea1SDimitry Andric // from applying this index is artificial. Artificial subregister 85*0fca6ea1SDimitry Andric // indexes are not used to create new register classes. 86*0fca6ea1SDimitry Andric bool Artificial; 87*0fca6ea1SDimitry Andric 88*0fca6ea1SDimitry Andric CodeGenSubRegIndex(Record *R, unsigned Enum, const CodeGenHwModes &CGH); 89*0fca6ea1SDimitry Andric CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum); 90*0fca6ea1SDimitry Andric CodeGenSubRegIndex(CodeGenSubRegIndex &) = delete; 91*0fca6ea1SDimitry Andric 92*0fca6ea1SDimitry Andric const std::string &getName() const { return Name; } 93*0fca6ea1SDimitry Andric const std::string &getNamespace() const { return Namespace; } 94*0fca6ea1SDimitry Andric std::string getQualifiedName() const; 95*0fca6ea1SDimitry Andric 96*0fca6ea1SDimitry Andric // Map of composite subreg indices. 97*0fca6ea1SDimitry Andric typedef std::map<CodeGenSubRegIndex *, CodeGenSubRegIndex *, 98*0fca6ea1SDimitry Andric deref<std::less<>>> 99*0fca6ea1SDimitry Andric CompMap; 100*0fca6ea1SDimitry Andric 101*0fca6ea1SDimitry Andric // Returns the subreg index that results from composing this with Idx. 102*0fca6ea1SDimitry Andric // Returns NULL if this and Idx don't compose. 103*0fca6ea1SDimitry Andric CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const { 104*0fca6ea1SDimitry Andric CompMap::const_iterator I = Composed.find(Idx); 105*0fca6ea1SDimitry Andric return I == Composed.end() ? nullptr : I->second; 106*0fca6ea1SDimitry Andric } 107*0fca6ea1SDimitry Andric 108*0fca6ea1SDimitry Andric // Add a composite subreg index: this+A = B. 109*0fca6ea1SDimitry Andric // Return a conflicting composite, or NULL 110*0fca6ea1SDimitry Andric CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, CodeGenSubRegIndex *B, 111*0fca6ea1SDimitry Andric const CodeGenHwModes &CGH) { 112*0fca6ea1SDimitry Andric assert(A && B); 113*0fca6ea1SDimitry Andric std::pair<CompMap::iterator, bool> Ins = Composed.insert(std::pair(A, B)); 114*0fca6ea1SDimitry Andric 115*0fca6ea1SDimitry Andric // Synthetic subreg indices that aren't contiguous (for instance ARM 116*0fca6ea1SDimitry Andric // register tuples) don't have a bit range, so it's OK to let 117*0fca6ea1SDimitry Andric // B->Offset == -1. For the other cases, accumulate the offset and set 118*0fca6ea1SDimitry Andric // the size here. Only do so if there is no offset yet though. 119*0fca6ea1SDimitry Andric unsigned NumModes = CGH.getNumModeIds(); 120*0fca6ea1SDimitry Andric // Skip default mode. 121*0fca6ea1SDimitry Andric for (unsigned M = 0; M < NumModes; ++M) { 122*0fca6ea1SDimitry Andric // Handle DefaultMode last. 123*0fca6ea1SDimitry Andric if (M == DefaultMode) 124*0fca6ea1SDimitry Andric continue; 125*0fca6ea1SDimitry Andric SubRegRange &Range = this->Range.get(M); 126*0fca6ea1SDimitry Andric SubRegRange &ARange = A->Range.get(M); 127*0fca6ea1SDimitry Andric SubRegRange &BRange = B->Range.get(M); 128*0fca6ea1SDimitry Andric 129*0fca6ea1SDimitry Andric if (Range.Offset != (uint16_t)-1 && ARange.Offset != (uint16_t)-1 && 130*0fca6ea1SDimitry Andric BRange.Offset == (uint16_t)-1) { 131*0fca6ea1SDimitry Andric BRange.Offset = Range.Offset + ARange.Offset; 132*0fca6ea1SDimitry Andric BRange.Size = ARange.Size; 133*0fca6ea1SDimitry Andric } 134*0fca6ea1SDimitry Andric } 135*0fca6ea1SDimitry Andric 136*0fca6ea1SDimitry Andric // Now handle default. 137*0fca6ea1SDimitry Andric SubRegRange &Range = this->Range.get(DefaultMode); 138*0fca6ea1SDimitry Andric SubRegRange &ARange = A->Range.get(DefaultMode); 139*0fca6ea1SDimitry Andric SubRegRange &BRange = B->Range.get(DefaultMode); 140*0fca6ea1SDimitry Andric if (Range.Offset != (uint16_t)-1 && ARange.Offset != (uint16_t)-1 && 141*0fca6ea1SDimitry Andric BRange.Offset == (uint16_t)-1) { 142*0fca6ea1SDimitry Andric BRange.Offset = Range.Offset + ARange.Offset; 143*0fca6ea1SDimitry Andric BRange.Size = ARange.Size; 144*0fca6ea1SDimitry Andric } 145*0fca6ea1SDimitry Andric 146*0fca6ea1SDimitry Andric return (Ins.second || Ins.first->second == B) ? nullptr : Ins.first->second; 147*0fca6ea1SDimitry Andric } 148*0fca6ea1SDimitry Andric 149*0fca6ea1SDimitry Andric // Update the composite maps of components specified in 'ComposedOf'. 150*0fca6ea1SDimitry Andric void updateComponents(CodeGenRegBank &); 151*0fca6ea1SDimitry Andric 152*0fca6ea1SDimitry Andric // Return the map of composites. 153*0fca6ea1SDimitry Andric const CompMap &getComposites() const { return Composed; } 154*0fca6ea1SDimitry Andric 155*0fca6ea1SDimitry Andric // Compute LaneMask from Composed. Return LaneMask. 156*0fca6ea1SDimitry Andric LaneBitmask computeLaneMask() const; 157*0fca6ea1SDimitry Andric 158*0fca6ea1SDimitry Andric void setConcatenationOf(ArrayRef<CodeGenSubRegIndex *> Parts); 159*0fca6ea1SDimitry Andric 160*0fca6ea1SDimitry Andric /// Replaces subregister indexes in the `ConcatenationOf` list with 161*0fca6ea1SDimitry Andric /// list of subregisters they are composed of (if any). Do this recursively. 162*0fca6ea1SDimitry Andric void computeConcatTransitiveClosure(); 163*0fca6ea1SDimitry Andric 164*0fca6ea1SDimitry Andric bool operator<(const CodeGenSubRegIndex &RHS) const { 165*0fca6ea1SDimitry Andric return this->EnumValue < RHS.EnumValue; 166*0fca6ea1SDimitry Andric } 167*0fca6ea1SDimitry Andric 168*0fca6ea1SDimitry Andric private: 169*0fca6ea1SDimitry Andric CompMap Composed; 170*0fca6ea1SDimitry Andric }; 171*0fca6ea1SDimitry Andric 172*0fca6ea1SDimitry Andric /// CodeGenRegister - Represents a register definition. 173*0fca6ea1SDimitry Andric class CodeGenRegister { 174*0fca6ea1SDimitry Andric public: 175*0fca6ea1SDimitry Andric Record *TheDef; 176*0fca6ea1SDimitry Andric unsigned EnumValue; 177*0fca6ea1SDimitry Andric std::vector<int64_t> CostPerUse; 178*0fca6ea1SDimitry Andric bool CoveredBySubRegs = true; 179*0fca6ea1SDimitry Andric bool HasDisjunctSubRegs = false; 180*0fca6ea1SDimitry Andric bool Artificial = true; 181*0fca6ea1SDimitry Andric bool Constant = false; 182*0fca6ea1SDimitry Andric 183*0fca6ea1SDimitry Andric // Map SubRegIndex -> Register. 184*0fca6ea1SDimitry Andric typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, deref<std::less<>>> 185*0fca6ea1SDimitry Andric SubRegMap; 186*0fca6ea1SDimitry Andric 187*0fca6ea1SDimitry Andric CodeGenRegister(Record *R, unsigned Enum); 188*0fca6ea1SDimitry Andric 189*0fca6ea1SDimitry Andric StringRef getName() const; 190*0fca6ea1SDimitry Andric 191*0fca6ea1SDimitry Andric // Extract more information from TheDef. This is used to build an object 192*0fca6ea1SDimitry Andric // graph after all CodeGenRegister objects have been created. 193*0fca6ea1SDimitry Andric void buildObjectGraph(CodeGenRegBank &); 194*0fca6ea1SDimitry Andric 195*0fca6ea1SDimitry Andric // Lazily compute a map of all sub-registers. 196*0fca6ea1SDimitry Andric // This includes unique entries for all sub-sub-registers. 197*0fca6ea1SDimitry Andric const SubRegMap &computeSubRegs(CodeGenRegBank &); 198*0fca6ea1SDimitry Andric 199*0fca6ea1SDimitry Andric // Compute extra sub-registers by combining the existing sub-registers. 200*0fca6ea1SDimitry Andric void computeSecondarySubRegs(CodeGenRegBank &); 201*0fca6ea1SDimitry Andric 202*0fca6ea1SDimitry Andric // Add this as a super-register to all sub-registers after the sub-register 203*0fca6ea1SDimitry Andric // graph has been built. 204*0fca6ea1SDimitry Andric void computeSuperRegs(CodeGenRegBank &); 205*0fca6ea1SDimitry Andric 206*0fca6ea1SDimitry Andric const SubRegMap &getSubRegs() const { 207*0fca6ea1SDimitry Andric assert(SubRegsComplete && "Must precompute sub-registers"); 208*0fca6ea1SDimitry Andric return SubRegs; 209*0fca6ea1SDimitry Andric } 210*0fca6ea1SDimitry Andric 211*0fca6ea1SDimitry Andric // Add sub-registers to OSet following a pre-order defined by the .td file. 212*0fca6ea1SDimitry Andric void addSubRegsPreOrder(SetVector<const CodeGenRegister *> &OSet, 213*0fca6ea1SDimitry Andric CodeGenRegBank &) const; 214*0fca6ea1SDimitry Andric 215*0fca6ea1SDimitry Andric // Return the sub-register index naming Reg as a sub-register of this 216*0fca6ea1SDimitry Andric // register. Returns NULL if Reg is not a sub-register. 217*0fca6ea1SDimitry Andric CodeGenSubRegIndex *getSubRegIndex(const CodeGenRegister *Reg) const { 218*0fca6ea1SDimitry Andric return SubReg2Idx.lookup(Reg); 219*0fca6ea1SDimitry Andric } 220*0fca6ea1SDimitry Andric 221*0fca6ea1SDimitry Andric typedef std::vector<const CodeGenRegister *> SuperRegList; 222*0fca6ea1SDimitry Andric 223*0fca6ea1SDimitry Andric // Get the list of super-registers in topological order, small to large. 224*0fca6ea1SDimitry Andric // This is valid after computeSubRegs visits all registers during RegBank 225*0fca6ea1SDimitry Andric // construction. 226*0fca6ea1SDimitry Andric const SuperRegList &getSuperRegs() const { 227*0fca6ea1SDimitry Andric assert(SubRegsComplete && "Must precompute sub-registers"); 228*0fca6ea1SDimitry Andric return SuperRegs; 229*0fca6ea1SDimitry Andric } 230*0fca6ea1SDimitry Andric 231*0fca6ea1SDimitry Andric // Get the list of ad hoc aliases. The graph is symmetric, so the list 232*0fca6ea1SDimitry Andric // contains all registers in 'Aliases', and all registers that mention this 233*0fca6ea1SDimitry Andric // register in 'Aliases'. 234*0fca6ea1SDimitry Andric ArrayRef<CodeGenRegister *> getExplicitAliases() const { 235*0fca6ea1SDimitry Andric return ExplicitAliases; 236*0fca6ea1SDimitry Andric } 237*0fca6ea1SDimitry Andric 238*0fca6ea1SDimitry Andric // Get the topological signature of this register. This is a small integer 239*0fca6ea1SDimitry Andric // less than RegBank.getNumTopoSigs(). Registers with the same TopoSig have 240*0fca6ea1SDimitry Andric // identical sub-register structure. That is, they support the same set of 241*0fca6ea1SDimitry Andric // sub-register indices mapping to the same kind of sub-registers 242*0fca6ea1SDimitry Andric // (TopoSig-wise). 243*0fca6ea1SDimitry Andric unsigned getTopoSig() const { 244*0fca6ea1SDimitry Andric assert(SuperRegsComplete && "TopoSigs haven't been computed yet."); 245*0fca6ea1SDimitry Andric return TopoSig; 246*0fca6ea1SDimitry Andric } 247*0fca6ea1SDimitry Andric 248*0fca6ea1SDimitry Andric // List of register units in ascending order. 249*0fca6ea1SDimitry Andric typedef SparseBitVector<> RegUnitList; 250*0fca6ea1SDimitry Andric typedef SmallVector<LaneBitmask, 16> RegUnitLaneMaskList; 251*0fca6ea1SDimitry Andric 252*0fca6ea1SDimitry Andric // How many entries in RegUnitList are native? 253*0fca6ea1SDimitry Andric RegUnitList NativeRegUnits; 254*0fca6ea1SDimitry Andric 255*0fca6ea1SDimitry Andric // Get the list of register units. 256*0fca6ea1SDimitry Andric // This is only valid after computeSubRegs() completes. 257*0fca6ea1SDimitry Andric const RegUnitList &getRegUnits() const { return RegUnits; } 258*0fca6ea1SDimitry Andric 259*0fca6ea1SDimitry Andric ArrayRef<LaneBitmask> getRegUnitLaneMasks() const { 260*0fca6ea1SDimitry Andric return ArrayRef(RegUnitLaneMasks).slice(0, NativeRegUnits.count()); 261*0fca6ea1SDimitry Andric } 262*0fca6ea1SDimitry Andric 263*0fca6ea1SDimitry Andric // Get the native register units. This is a prefix of getRegUnits(). 264*0fca6ea1SDimitry Andric RegUnitList getNativeRegUnits() const { return NativeRegUnits; } 265*0fca6ea1SDimitry Andric 266*0fca6ea1SDimitry Andric void setRegUnitLaneMasks(const RegUnitLaneMaskList &LaneMasks) { 267*0fca6ea1SDimitry Andric RegUnitLaneMasks = LaneMasks; 268*0fca6ea1SDimitry Andric } 269*0fca6ea1SDimitry Andric 270*0fca6ea1SDimitry Andric // Inherit register units from subregisters. 271*0fca6ea1SDimitry Andric // Return true if the RegUnits changed. 272*0fca6ea1SDimitry Andric bool inheritRegUnits(CodeGenRegBank &RegBank); 273*0fca6ea1SDimitry Andric 274*0fca6ea1SDimitry Andric // Adopt a register unit for pressure tracking. 275*0fca6ea1SDimitry Andric // A unit is adopted iff its unit number is >= NativeRegUnits.count(). 276*0fca6ea1SDimitry Andric void adoptRegUnit(unsigned RUID) { RegUnits.set(RUID); } 277*0fca6ea1SDimitry Andric 278*0fca6ea1SDimitry Andric // Get the sum of this register's register unit weights. 279*0fca6ea1SDimitry Andric unsigned getWeight(const CodeGenRegBank &RegBank) const; 280*0fca6ea1SDimitry Andric 281*0fca6ea1SDimitry Andric // Canonically ordered set. 282*0fca6ea1SDimitry Andric typedef std::vector<const CodeGenRegister *> Vec; 283*0fca6ea1SDimitry Andric 284*0fca6ea1SDimitry Andric private: 285*0fca6ea1SDimitry Andric bool SubRegsComplete; 286*0fca6ea1SDimitry Andric bool SuperRegsComplete; 287*0fca6ea1SDimitry Andric unsigned TopoSig; 288*0fca6ea1SDimitry Andric 289*0fca6ea1SDimitry Andric // The sub-registers explicit in the .td file form a tree. 290*0fca6ea1SDimitry Andric SmallVector<CodeGenSubRegIndex *, 8> ExplicitSubRegIndices; 291*0fca6ea1SDimitry Andric SmallVector<CodeGenRegister *, 8> ExplicitSubRegs; 292*0fca6ea1SDimitry Andric 293*0fca6ea1SDimitry Andric // Explicit ad hoc aliases, symmetrized to form an undirected graph. 294*0fca6ea1SDimitry Andric SmallVector<CodeGenRegister *, 8> ExplicitAliases; 295*0fca6ea1SDimitry Andric 296*0fca6ea1SDimitry Andric // Super-registers where this is the first explicit sub-register. 297*0fca6ea1SDimitry Andric SuperRegList LeadingSuperRegs; 298*0fca6ea1SDimitry Andric 299*0fca6ea1SDimitry Andric SubRegMap SubRegs; 300*0fca6ea1SDimitry Andric SuperRegList SuperRegs; 301*0fca6ea1SDimitry Andric DenseMap<const CodeGenRegister *, CodeGenSubRegIndex *> SubReg2Idx; 302*0fca6ea1SDimitry Andric RegUnitList RegUnits; 303*0fca6ea1SDimitry Andric RegUnitLaneMaskList RegUnitLaneMasks; 304*0fca6ea1SDimitry Andric }; 305*0fca6ea1SDimitry Andric 306*0fca6ea1SDimitry Andric inline bool operator<(const CodeGenRegister &A, const CodeGenRegister &B) { 307*0fca6ea1SDimitry Andric return A.EnumValue < B.EnumValue; 308*0fca6ea1SDimitry Andric } 309*0fca6ea1SDimitry Andric 310*0fca6ea1SDimitry Andric inline bool operator==(const CodeGenRegister &A, const CodeGenRegister &B) { 311*0fca6ea1SDimitry Andric return A.EnumValue == B.EnumValue; 312*0fca6ea1SDimitry Andric } 313*0fca6ea1SDimitry Andric 314*0fca6ea1SDimitry Andric class CodeGenRegisterClass { 315*0fca6ea1SDimitry Andric CodeGenRegister::Vec Members; 316*0fca6ea1SDimitry Andric // Allocation orders. Order[0] always contains all registers in Members. 317*0fca6ea1SDimitry Andric std::vector<SmallVector<Record *, 16>> Orders; 318*0fca6ea1SDimitry Andric // Bit mask of sub-classes including this, indexed by their EnumValue. 319*0fca6ea1SDimitry Andric BitVector SubClasses; 320*0fca6ea1SDimitry Andric // List of super-classes, topologocally ordered to have the larger classes 321*0fca6ea1SDimitry Andric // first. This is the same as sorting by EnumValue. 322*0fca6ea1SDimitry Andric SmallVector<CodeGenRegisterClass *, 4> SuperClasses; 323*0fca6ea1SDimitry Andric Record *TheDef; 324*0fca6ea1SDimitry Andric std::string Name; 325*0fca6ea1SDimitry Andric 326*0fca6ea1SDimitry Andric // For a synthesized class, inherit missing properties from the nearest 327*0fca6ea1SDimitry Andric // super-class. 328*0fca6ea1SDimitry Andric void inheritProperties(CodeGenRegBank &); 329*0fca6ea1SDimitry Andric 330*0fca6ea1SDimitry Andric // Map SubRegIndex -> sub-class. This is the largest sub-class where all 331*0fca6ea1SDimitry Andric // registers have a SubRegIndex sub-register. 332*0fca6ea1SDimitry Andric DenseMap<const CodeGenSubRegIndex *, CodeGenRegisterClass *> 333*0fca6ea1SDimitry Andric SubClassWithSubReg; 334*0fca6ea1SDimitry Andric 335*0fca6ea1SDimitry Andric // Map SubRegIndex -> set of super-reg classes. This is all register 336*0fca6ea1SDimitry Andric // classes SuperRC such that: 337*0fca6ea1SDimitry Andric // 338*0fca6ea1SDimitry Andric // R:SubRegIndex in this RC for all R in SuperRC. 339*0fca6ea1SDimitry Andric // 340*0fca6ea1SDimitry Andric DenseMap<const CodeGenSubRegIndex *, SmallPtrSet<CodeGenRegisterClass *, 8>> 341*0fca6ea1SDimitry Andric SuperRegClasses; 342*0fca6ea1SDimitry Andric 343*0fca6ea1SDimitry Andric // Bit vector of TopoSigs for the registers in this class. This will be 344*0fca6ea1SDimitry Andric // very sparse on regular architectures. 345*0fca6ea1SDimitry Andric BitVector TopoSigs; 346*0fca6ea1SDimitry Andric 347*0fca6ea1SDimitry Andric public: 348*0fca6ea1SDimitry Andric unsigned EnumValue; 349*0fca6ea1SDimitry Andric StringRef Namespace; 350*0fca6ea1SDimitry Andric SmallVector<ValueTypeByHwMode, 4> VTs; 351*0fca6ea1SDimitry Andric RegSizeInfoByHwMode RSI; 352*0fca6ea1SDimitry Andric int CopyCost; 353*0fca6ea1SDimitry Andric bool Allocatable; 354*0fca6ea1SDimitry Andric StringRef AltOrderSelect; 355*0fca6ea1SDimitry Andric uint8_t AllocationPriority; 356*0fca6ea1SDimitry Andric bool GlobalPriority; 357*0fca6ea1SDimitry Andric uint8_t TSFlags; 358*0fca6ea1SDimitry Andric /// Contains the combination of the lane masks of all subregisters. 359*0fca6ea1SDimitry Andric LaneBitmask LaneMask; 360*0fca6ea1SDimitry Andric /// True if there are at least 2 subregisters which do not interfere. 361*0fca6ea1SDimitry Andric bool HasDisjunctSubRegs; 362*0fca6ea1SDimitry Andric bool CoveredBySubRegs; 363*0fca6ea1SDimitry Andric /// A register class is artificial if all its members are artificial. 364*0fca6ea1SDimitry Andric bool Artificial; 365*0fca6ea1SDimitry Andric /// Generate register pressure set for this register class and any class 366*0fca6ea1SDimitry Andric /// synthesized from it. 367*0fca6ea1SDimitry Andric bool GeneratePressureSet; 368*0fca6ea1SDimitry Andric 369*0fca6ea1SDimitry Andric // Return the Record that defined this class, or NULL if the class was 370*0fca6ea1SDimitry Andric // created by TableGen. 371*0fca6ea1SDimitry Andric Record *getDef() const { return TheDef; } 372*0fca6ea1SDimitry Andric 373*0fca6ea1SDimitry Andric std::string getNamespaceQualification() const; 374*0fca6ea1SDimitry Andric const std::string &getName() const { return Name; } 375*0fca6ea1SDimitry Andric std::string getQualifiedName() const; 376*0fca6ea1SDimitry Andric std::string getIdName() const; 377*0fca6ea1SDimitry Andric std::string getQualifiedIdName() const; 378*0fca6ea1SDimitry Andric ArrayRef<ValueTypeByHwMode> getValueTypes() const { return VTs; } 379*0fca6ea1SDimitry Andric unsigned getNumValueTypes() const { return VTs.size(); } 380*0fca6ea1SDimitry Andric bool hasType(const ValueTypeByHwMode &VT) const; 381*0fca6ea1SDimitry Andric 382*0fca6ea1SDimitry Andric const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const { 383*0fca6ea1SDimitry Andric if (VTNum < VTs.size()) 384*0fca6ea1SDimitry Andric return VTs[VTNum]; 385*0fca6ea1SDimitry Andric llvm_unreachable("VTNum greater than number of ValueTypes in RegClass!"); 386*0fca6ea1SDimitry Andric } 387*0fca6ea1SDimitry Andric 388*0fca6ea1SDimitry Andric // Return true if this class contains the register. 389*0fca6ea1SDimitry Andric bool contains(const CodeGenRegister *) const; 390*0fca6ea1SDimitry Andric 391*0fca6ea1SDimitry Andric // Returns true if RC is a subclass. 392*0fca6ea1SDimitry Andric // RC is a sub-class of this class if it is a valid replacement for any 393*0fca6ea1SDimitry Andric // instruction operand where a register of this classis required. It must 394*0fca6ea1SDimitry Andric // satisfy these conditions: 395*0fca6ea1SDimitry Andric // 396*0fca6ea1SDimitry Andric // 1. All RC registers are also in this. 397*0fca6ea1SDimitry Andric // 2. The RC spill size must not be smaller than our spill size. 398*0fca6ea1SDimitry Andric // 3. RC spill alignment must be compatible with ours. 399*0fca6ea1SDimitry Andric // 400*0fca6ea1SDimitry Andric bool hasSubClass(const CodeGenRegisterClass *RC) const { 401*0fca6ea1SDimitry Andric return SubClasses.test(RC->EnumValue); 402*0fca6ea1SDimitry Andric } 403*0fca6ea1SDimitry Andric 404*0fca6ea1SDimitry Andric // getSubClassWithSubReg - Returns the largest sub-class where all 405*0fca6ea1SDimitry Andric // registers have a SubIdx sub-register. 406*0fca6ea1SDimitry Andric CodeGenRegisterClass * 407*0fca6ea1SDimitry Andric getSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx) const { 408*0fca6ea1SDimitry Andric return SubClassWithSubReg.lookup(SubIdx); 409*0fca6ea1SDimitry Andric } 410*0fca6ea1SDimitry Andric 411*0fca6ea1SDimitry Andric /// Find largest subclass where all registers have SubIdx subregisters in 412*0fca6ea1SDimitry Andric /// SubRegClass and the largest subregister class that contains those 413*0fca6ea1SDimitry Andric /// subregisters without (as far as possible) also containing additional 414*0fca6ea1SDimitry Andric /// registers. 415*0fca6ea1SDimitry Andric /// 416*0fca6ea1SDimitry Andric /// This can be used to find a suitable pair of classes for subregister 417*0fca6ea1SDimitry Andric /// copies. \return std::pair<SubClass, SubRegClass> where SubClass is a 418*0fca6ea1SDimitry Andric /// SubClass is a class where every register has SubIdx and SubRegClass is a 419*0fca6ea1SDimitry Andric /// class where every register is covered by the SubIdx subregister of 420*0fca6ea1SDimitry Andric /// SubClass. 421*0fca6ea1SDimitry Andric std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>> 422*0fca6ea1SDimitry Andric getMatchingSubClassWithSubRegs(CodeGenRegBank &RegBank, 423*0fca6ea1SDimitry Andric const CodeGenSubRegIndex *SubIdx) const; 424*0fca6ea1SDimitry Andric 425*0fca6ea1SDimitry Andric void setSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx, 426*0fca6ea1SDimitry Andric CodeGenRegisterClass *SubRC) { 427*0fca6ea1SDimitry Andric SubClassWithSubReg[SubIdx] = SubRC; 428*0fca6ea1SDimitry Andric } 429*0fca6ea1SDimitry Andric 430*0fca6ea1SDimitry Andric // getSuperRegClasses - Returns a bit vector of all register classes 431*0fca6ea1SDimitry Andric // containing only SubIdx super-registers of this class. 432*0fca6ea1SDimitry Andric void getSuperRegClasses(const CodeGenSubRegIndex *SubIdx, 433*0fca6ea1SDimitry Andric BitVector &Out) const; 434*0fca6ea1SDimitry Andric 435*0fca6ea1SDimitry Andric // addSuperRegClass - Add a class containing only SubIdx super-registers. 436*0fca6ea1SDimitry Andric void addSuperRegClass(CodeGenSubRegIndex *SubIdx, 437*0fca6ea1SDimitry Andric CodeGenRegisterClass *SuperRC) { 438*0fca6ea1SDimitry Andric SuperRegClasses[SubIdx].insert(SuperRC); 439*0fca6ea1SDimitry Andric } 440*0fca6ea1SDimitry Andric 441*0fca6ea1SDimitry Andric // getSubClasses - Returns a constant BitVector of subclasses indexed by 442*0fca6ea1SDimitry Andric // EnumValue. 443*0fca6ea1SDimitry Andric // The SubClasses vector includes an entry for this class. 444*0fca6ea1SDimitry Andric const BitVector &getSubClasses() const { return SubClasses; } 445*0fca6ea1SDimitry Andric 446*0fca6ea1SDimitry Andric // getSuperClasses - Returns a list of super classes ordered by EnumValue. 447*0fca6ea1SDimitry Andric // The array does not include an entry for this class. 448*0fca6ea1SDimitry Andric ArrayRef<CodeGenRegisterClass *> getSuperClasses() const { 449*0fca6ea1SDimitry Andric return SuperClasses; 450*0fca6ea1SDimitry Andric } 451*0fca6ea1SDimitry Andric 452*0fca6ea1SDimitry Andric // Returns an ordered list of class members. 453*0fca6ea1SDimitry Andric // The order of registers is the same as in the .td file. 454*0fca6ea1SDimitry Andric // No = 0 is the default allocation order, No = 1 is the first alternative. 455*0fca6ea1SDimitry Andric ArrayRef<Record *> getOrder(unsigned No = 0) const { return Orders[No]; } 456*0fca6ea1SDimitry Andric 457*0fca6ea1SDimitry Andric // Return the total number of allocation orders available. 458*0fca6ea1SDimitry Andric unsigned getNumOrders() const { return Orders.size(); } 459*0fca6ea1SDimitry Andric 460*0fca6ea1SDimitry Andric // Get the set of registers. This set contains the same registers as 461*0fca6ea1SDimitry Andric // getOrder(0). 462*0fca6ea1SDimitry Andric const CodeGenRegister::Vec &getMembers() const { return Members; } 463*0fca6ea1SDimitry Andric 464*0fca6ea1SDimitry Andric // Get a bit vector of TopoSigs present in this register class. 465*0fca6ea1SDimitry Andric const BitVector &getTopoSigs() const { return TopoSigs; } 466*0fca6ea1SDimitry Andric 467*0fca6ea1SDimitry Andric // Get a weight of this register class. 468*0fca6ea1SDimitry Andric unsigned getWeight(const CodeGenRegBank &) const; 469*0fca6ea1SDimitry Andric 470*0fca6ea1SDimitry Andric // Populate a unique sorted list of units from a register set. 471*0fca6ea1SDimitry Andric void buildRegUnitSet(const CodeGenRegBank &RegBank, 472*0fca6ea1SDimitry Andric std::vector<unsigned> &RegUnits) const; 473*0fca6ea1SDimitry Andric 474*0fca6ea1SDimitry Andric CodeGenRegisterClass(CodeGenRegBank &, Record *R); 475*0fca6ea1SDimitry Andric CodeGenRegisterClass(CodeGenRegisterClass &) = delete; 476*0fca6ea1SDimitry Andric 477*0fca6ea1SDimitry Andric // A key representing the parts of a register class used for forming 478*0fca6ea1SDimitry Andric // sub-classes. Note the ordering provided by this key is not the same as 479*0fca6ea1SDimitry Andric // the topological order used for the EnumValues. 480*0fca6ea1SDimitry Andric struct Key { 481*0fca6ea1SDimitry Andric const CodeGenRegister::Vec *Members; 482*0fca6ea1SDimitry Andric RegSizeInfoByHwMode RSI; 483*0fca6ea1SDimitry Andric 484*0fca6ea1SDimitry Andric Key(const CodeGenRegister::Vec *M, const RegSizeInfoByHwMode &I) 485*0fca6ea1SDimitry Andric : Members(M), RSI(I) {} 486*0fca6ea1SDimitry Andric 487*0fca6ea1SDimitry Andric Key(const CodeGenRegisterClass &RC) 488*0fca6ea1SDimitry Andric : Members(&RC.getMembers()), RSI(RC.RSI) {} 489*0fca6ea1SDimitry Andric 490*0fca6ea1SDimitry Andric // Lexicographical order of (Members, RegSizeInfoByHwMode). 491*0fca6ea1SDimitry Andric bool operator<(const Key &) const; 492*0fca6ea1SDimitry Andric }; 493*0fca6ea1SDimitry Andric 494*0fca6ea1SDimitry Andric // Create a non-user defined register class. 495*0fca6ea1SDimitry Andric CodeGenRegisterClass(CodeGenRegBank &, StringRef Name, Key Props); 496*0fca6ea1SDimitry Andric 497*0fca6ea1SDimitry Andric // Called by CodeGenRegBank::CodeGenRegBank(). 498*0fca6ea1SDimitry Andric static void computeSubClasses(CodeGenRegBank &); 499*0fca6ea1SDimitry Andric 500*0fca6ea1SDimitry Andric // Get ordering value among register base classes. 501*0fca6ea1SDimitry Andric std::optional<int> getBaseClassOrder() const { 502*0fca6ea1SDimitry Andric if (TheDef && !TheDef->isValueUnset("BaseClassOrder")) 503*0fca6ea1SDimitry Andric return TheDef->getValueAsInt("BaseClassOrder"); 504*0fca6ea1SDimitry Andric return {}; 505*0fca6ea1SDimitry Andric } 506*0fca6ea1SDimitry Andric }; 507*0fca6ea1SDimitry Andric 508*0fca6ea1SDimitry Andric // Register categories are used when we need to deterine the category a 509*0fca6ea1SDimitry Andric // register falls into (GPR, vector, fixed, etc.) without having to know 510*0fca6ea1SDimitry Andric // specific information about the target architecture. 511*0fca6ea1SDimitry Andric class CodeGenRegisterCategory { 512*0fca6ea1SDimitry Andric Record *TheDef; 513*0fca6ea1SDimitry Andric std::string Name; 514*0fca6ea1SDimitry Andric std::list<CodeGenRegisterClass *> Classes; 515*0fca6ea1SDimitry Andric 516*0fca6ea1SDimitry Andric public: 517*0fca6ea1SDimitry Andric CodeGenRegisterCategory(CodeGenRegBank &, Record *R); 518*0fca6ea1SDimitry Andric CodeGenRegisterCategory(CodeGenRegisterCategory &) = delete; 519*0fca6ea1SDimitry Andric 520*0fca6ea1SDimitry Andric // Return the Record that defined this class, or NULL if the class was 521*0fca6ea1SDimitry Andric // created by TableGen. 522*0fca6ea1SDimitry Andric Record *getDef() const { return TheDef; } 523*0fca6ea1SDimitry Andric 524*0fca6ea1SDimitry Andric std::string getName() const { return Name; } 525*0fca6ea1SDimitry Andric std::list<CodeGenRegisterClass *> getClasses() const { return Classes; } 526*0fca6ea1SDimitry Andric }; 527*0fca6ea1SDimitry Andric 528*0fca6ea1SDimitry Andric // Register units are used to model interference and register pressure. 529*0fca6ea1SDimitry Andric // Every register is assigned one or more register units such that two 530*0fca6ea1SDimitry Andric // registers overlap if and only if they have a register unit in common. 531*0fca6ea1SDimitry Andric // 532*0fca6ea1SDimitry Andric // Normally, one register unit is created per leaf register. Non-leaf 533*0fca6ea1SDimitry Andric // registers inherit the units of their sub-registers. 534*0fca6ea1SDimitry Andric struct RegUnit { 535*0fca6ea1SDimitry Andric // Weight assigned to this RegUnit for estimating register pressure. 536*0fca6ea1SDimitry Andric // This is useful when equalizing weights in register classes with mixed 537*0fca6ea1SDimitry Andric // register topologies. 538*0fca6ea1SDimitry Andric unsigned Weight; 539*0fca6ea1SDimitry Andric 540*0fca6ea1SDimitry Andric // Each native RegUnit corresponds to one or two root registers. The full 541*0fca6ea1SDimitry Andric // set of registers containing this unit can be computed as the union of 542*0fca6ea1SDimitry Andric // these two registers and their super-registers. 543*0fca6ea1SDimitry Andric const CodeGenRegister *Roots[2]; 544*0fca6ea1SDimitry Andric 545*0fca6ea1SDimitry Andric // Index into RegClassUnitSets where we can find the list of UnitSets that 546*0fca6ea1SDimitry Andric // contain this unit. 547*0fca6ea1SDimitry Andric unsigned RegClassUnitSetsIdx; 548*0fca6ea1SDimitry Andric // A register unit is artificial if at least one of its roots is 549*0fca6ea1SDimitry Andric // artificial. 550*0fca6ea1SDimitry Andric bool Artificial; 551*0fca6ea1SDimitry Andric 552*0fca6ea1SDimitry Andric RegUnit() : Weight(0), RegClassUnitSetsIdx(0), Artificial(false) { 553*0fca6ea1SDimitry Andric Roots[0] = Roots[1] = nullptr; 554*0fca6ea1SDimitry Andric } 555*0fca6ea1SDimitry Andric 556*0fca6ea1SDimitry Andric ArrayRef<const CodeGenRegister *> getRoots() const { 557*0fca6ea1SDimitry Andric assert(!(Roots[1] && !Roots[0]) && "Invalid roots array"); 558*0fca6ea1SDimitry Andric return ArrayRef(Roots, !!Roots[0] + !!Roots[1]); 559*0fca6ea1SDimitry Andric } 560*0fca6ea1SDimitry Andric }; 561*0fca6ea1SDimitry Andric 562*0fca6ea1SDimitry Andric // Each RegUnitSet is a sorted vector with a name. 563*0fca6ea1SDimitry Andric struct RegUnitSet { 564*0fca6ea1SDimitry Andric typedef std::vector<unsigned>::const_iterator iterator; 565*0fca6ea1SDimitry Andric 566*0fca6ea1SDimitry Andric std::string Name; 567*0fca6ea1SDimitry Andric std::vector<unsigned> Units; 568*0fca6ea1SDimitry Andric unsigned Weight = 0; // Cache the sum of all unit weights. 569*0fca6ea1SDimitry Andric unsigned Order = 0; // Cache the sort key. 570*0fca6ea1SDimitry Andric 571*0fca6ea1SDimitry Andric RegUnitSet(std::string Name) : Name(Name) {} 572*0fca6ea1SDimitry Andric }; 573*0fca6ea1SDimitry Andric 574*0fca6ea1SDimitry Andric // Base vector for identifying TopoSigs. The contents uniquely identify a 575*0fca6ea1SDimitry Andric // TopoSig, only computeSuperRegs needs to know how. 576*0fca6ea1SDimitry Andric typedef SmallVector<unsigned, 16> TopoSigId; 577*0fca6ea1SDimitry Andric 578*0fca6ea1SDimitry Andric // CodeGenRegBank - Represent a target's registers and the relations between 579*0fca6ea1SDimitry Andric // them. 580*0fca6ea1SDimitry Andric class CodeGenRegBank { 581*0fca6ea1SDimitry Andric SetTheory Sets; 582*0fca6ea1SDimitry Andric 583*0fca6ea1SDimitry Andric const CodeGenHwModes &CGH; 584*0fca6ea1SDimitry Andric 585*0fca6ea1SDimitry Andric std::deque<CodeGenSubRegIndex> SubRegIndices; 586*0fca6ea1SDimitry Andric DenseMap<Record *, CodeGenSubRegIndex *> Def2SubRegIdx; 587*0fca6ea1SDimitry Andric 588*0fca6ea1SDimitry Andric CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace); 589*0fca6ea1SDimitry Andric 590*0fca6ea1SDimitry Andric typedef std::map<SmallVector<CodeGenSubRegIndex *, 8>, CodeGenSubRegIndex *> 591*0fca6ea1SDimitry Andric ConcatIdxMap; 592*0fca6ea1SDimitry Andric ConcatIdxMap ConcatIdx; 593*0fca6ea1SDimitry Andric 594*0fca6ea1SDimitry Andric // Registers. 595*0fca6ea1SDimitry Andric std::deque<CodeGenRegister> Registers; 596*0fca6ea1SDimitry Andric StringMap<CodeGenRegister *> RegistersByName; 597*0fca6ea1SDimitry Andric DenseMap<Record *, CodeGenRegister *> Def2Reg; 598*0fca6ea1SDimitry Andric unsigned NumNativeRegUnits; 599*0fca6ea1SDimitry Andric 600*0fca6ea1SDimitry Andric std::map<TopoSigId, unsigned> TopoSigs; 601*0fca6ea1SDimitry Andric 602*0fca6ea1SDimitry Andric // Includes native (0..NumNativeRegUnits-1) and adopted register units. 603*0fca6ea1SDimitry Andric SmallVector<RegUnit, 8> RegUnits; 604*0fca6ea1SDimitry Andric 605*0fca6ea1SDimitry Andric // Register classes. 606*0fca6ea1SDimitry Andric std::list<CodeGenRegisterClass> RegClasses; 607*0fca6ea1SDimitry Andric DenseMap<Record *, CodeGenRegisterClass *> Def2RC; 608*0fca6ea1SDimitry Andric typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass *> RCKeyMap; 609*0fca6ea1SDimitry Andric RCKeyMap Key2RC; 610*0fca6ea1SDimitry Andric 611*0fca6ea1SDimitry Andric // Register categories. 612*0fca6ea1SDimitry Andric std::list<CodeGenRegisterCategory> RegCategories; 613*0fca6ea1SDimitry Andric DenseMap<Record *, CodeGenRegisterCategory *> Def2RCat; 614*0fca6ea1SDimitry Andric using RCatKeyMap = 615*0fca6ea1SDimitry Andric std::map<CodeGenRegisterClass::Key, CodeGenRegisterCategory *>; 616*0fca6ea1SDimitry Andric RCatKeyMap Key2RCat; 617*0fca6ea1SDimitry Andric 618*0fca6ea1SDimitry Andric // Remember each unique set of register units. Initially, this contains a 619*0fca6ea1SDimitry Andric // unique set for each register class. Simliar sets are coalesced with 620*0fca6ea1SDimitry Andric // pruneUnitSets and new supersets are inferred during computeRegUnitSets. 621*0fca6ea1SDimitry Andric std::vector<RegUnitSet> RegUnitSets; 622*0fca6ea1SDimitry Andric 623*0fca6ea1SDimitry Andric // Map RegisterClass index to the index of the RegUnitSet that contains the 624*0fca6ea1SDimitry Andric // class's units and any inferred RegUnit supersets. 625*0fca6ea1SDimitry Andric // 626*0fca6ea1SDimitry Andric // NOTE: This could grow beyond the number of register classes when we map 627*0fca6ea1SDimitry Andric // register units to lists of unit sets. If the list of unit sets does not 628*0fca6ea1SDimitry Andric // already exist for a register class, we create a new entry in this vector. 629*0fca6ea1SDimitry Andric std::vector<std::vector<unsigned>> RegClassUnitSets; 630*0fca6ea1SDimitry Andric 631*0fca6ea1SDimitry Andric // Give each register unit set an order based on sorting criteria. 632*0fca6ea1SDimitry Andric std::vector<unsigned> RegUnitSetOrder; 633*0fca6ea1SDimitry Andric 634*0fca6ea1SDimitry Andric // Keep track of synthesized definitions generated in TupleExpander. 635*0fca6ea1SDimitry Andric std::vector<std::unique_ptr<Record>> SynthDefs; 636*0fca6ea1SDimitry Andric 637*0fca6ea1SDimitry Andric // Add RC to *2RC maps. 638*0fca6ea1SDimitry Andric void addToMaps(CodeGenRegisterClass *); 639*0fca6ea1SDimitry Andric 640*0fca6ea1SDimitry Andric // Create a synthetic sub-class if it is missing. 641*0fca6ea1SDimitry Andric CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC, 642*0fca6ea1SDimitry Andric const CodeGenRegister::Vec *Membs, 643*0fca6ea1SDimitry Andric StringRef Name); 644*0fca6ea1SDimitry Andric 645*0fca6ea1SDimitry Andric // Infer missing register classes. 646*0fca6ea1SDimitry Andric void computeInferredRegisterClasses(); 647*0fca6ea1SDimitry Andric void inferCommonSubClass(CodeGenRegisterClass *RC); 648*0fca6ea1SDimitry Andric void inferSubClassWithSubReg(CodeGenRegisterClass *RC); 649*0fca6ea1SDimitry Andric 650*0fca6ea1SDimitry Andric void inferMatchingSuperRegClass(CodeGenRegisterClass *RC) { 651*0fca6ea1SDimitry Andric inferMatchingSuperRegClass(RC, RegClasses.begin()); 652*0fca6ea1SDimitry Andric } 653*0fca6ea1SDimitry Andric 654*0fca6ea1SDimitry Andric void inferMatchingSuperRegClass( 655*0fca6ea1SDimitry Andric CodeGenRegisterClass *RC, 656*0fca6ea1SDimitry Andric std::list<CodeGenRegisterClass>::iterator FirstSubRegRC); 657*0fca6ea1SDimitry Andric 658*0fca6ea1SDimitry Andric // Iteratively prune unit sets. 659*0fca6ea1SDimitry Andric void pruneUnitSets(); 660*0fca6ea1SDimitry Andric 661*0fca6ea1SDimitry Andric // Compute a weight for each register unit created during getSubRegs. 662*0fca6ea1SDimitry Andric void computeRegUnitWeights(); 663*0fca6ea1SDimitry Andric 664*0fca6ea1SDimitry Andric // Create a RegUnitSet for each RegClass and infer superclasses. 665*0fca6ea1SDimitry Andric void computeRegUnitSets(); 666*0fca6ea1SDimitry Andric 667*0fca6ea1SDimitry Andric // Populate the Composite map from sub-register relationships. 668*0fca6ea1SDimitry Andric void computeComposites(); 669*0fca6ea1SDimitry Andric 670*0fca6ea1SDimitry Andric // Compute a lane mask for each sub-register index. 671*0fca6ea1SDimitry Andric void computeSubRegLaneMasks(); 672*0fca6ea1SDimitry Andric 673*0fca6ea1SDimitry Andric /// Computes a lane mask for each register unit enumerated by a physical 674*0fca6ea1SDimitry Andric /// register. 675*0fca6ea1SDimitry Andric void computeRegUnitLaneMasks(); 676*0fca6ea1SDimitry Andric 677*0fca6ea1SDimitry Andric public: 678*0fca6ea1SDimitry Andric CodeGenRegBank(RecordKeeper &, const CodeGenHwModes &); 679*0fca6ea1SDimitry Andric CodeGenRegBank(CodeGenRegBank &) = delete; 680*0fca6ea1SDimitry Andric 681*0fca6ea1SDimitry Andric SetTheory &getSets() { return Sets; } 682*0fca6ea1SDimitry Andric 683*0fca6ea1SDimitry Andric const CodeGenHwModes &getHwModes() const { return CGH; } 684*0fca6ea1SDimitry Andric 685*0fca6ea1SDimitry Andric // Sub-register indices. The first NumNamedIndices are defined by the user 686*0fca6ea1SDimitry Andric // in the .td files. The rest are synthesized such that all sub-registers 687*0fca6ea1SDimitry Andric // have a unique name. 688*0fca6ea1SDimitry Andric const std::deque<CodeGenSubRegIndex> &getSubRegIndices() const { 689*0fca6ea1SDimitry Andric return SubRegIndices; 690*0fca6ea1SDimitry Andric } 691*0fca6ea1SDimitry Andric 692*0fca6ea1SDimitry Andric // Find a SubRegIndex from its Record def or add to the list if it does 693*0fca6ea1SDimitry Andric // not exist there yet. 694*0fca6ea1SDimitry Andric CodeGenSubRegIndex *getSubRegIdx(Record *); 695*0fca6ea1SDimitry Andric 696*0fca6ea1SDimitry Andric // Find a SubRegIndex from its Record def. 697*0fca6ea1SDimitry Andric const CodeGenSubRegIndex *findSubRegIdx(const Record *Def) const; 698*0fca6ea1SDimitry Andric 699*0fca6ea1SDimitry Andric // Find or create a sub-register index representing the A+B composition. 700*0fca6ea1SDimitry Andric CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A, 701*0fca6ea1SDimitry Andric CodeGenSubRegIndex *B); 702*0fca6ea1SDimitry Andric 703*0fca6ea1SDimitry Andric // Find or create a sub-register index representing the concatenation of 704*0fca6ea1SDimitry Andric // non-overlapping sibling indices. 705*0fca6ea1SDimitry Andric CodeGenSubRegIndex * 706*0fca6ea1SDimitry Andric getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &, 707*0fca6ea1SDimitry Andric const CodeGenHwModes &CGH); 708*0fca6ea1SDimitry Andric 709*0fca6ea1SDimitry Andric const std::deque<CodeGenRegister> &getRegisters() const { return Registers; } 710*0fca6ea1SDimitry Andric 711*0fca6ea1SDimitry Andric const StringMap<CodeGenRegister *> &getRegistersByName() const { 712*0fca6ea1SDimitry Andric return RegistersByName; 713*0fca6ea1SDimitry Andric } 714*0fca6ea1SDimitry Andric 715*0fca6ea1SDimitry Andric // Find a register from its Record def. 716*0fca6ea1SDimitry Andric CodeGenRegister *getReg(Record *); 717*0fca6ea1SDimitry Andric 718*0fca6ea1SDimitry Andric // Get a Register's index into the Registers array. 719*0fca6ea1SDimitry Andric unsigned getRegIndex(const CodeGenRegister *Reg) const { 720*0fca6ea1SDimitry Andric return Reg->EnumValue - 1; 721*0fca6ea1SDimitry Andric } 722*0fca6ea1SDimitry Andric 723*0fca6ea1SDimitry Andric // Return the number of allocated TopoSigs. The first TopoSig representing 724*0fca6ea1SDimitry Andric // leaf registers is allocated number 0. 725*0fca6ea1SDimitry Andric unsigned getNumTopoSigs() const { return TopoSigs.size(); } 726*0fca6ea1SDimitry Andric 727*0fca6ea1SDimitry Andric // Find or create a TopoSig for the given TopoSigId. 728*0fca6ea1SDimitry Andric // This function is only for use by CodeGenRegister::computeSuperRegs(). 729*0fca6ea1SDimitry Andric // Others should simply use Reg->getTopoSig(). 730*0fca6ea1SDimitry Andric unsigned getTopoSig(const TopoSigId &Id) { 731*0fca6ea1SDimitry Andric return TopoSigs.insert(std::pair(Id, TopoSigs.size())).first->second; 732*0fca6ea1SDimitry Andric } 733*0fca6ea1SDimitry Andric 734*0fca6ea1SDimitry Andric // Create a native register unit that is associated with one or two root 735*0fca6ea1SDimitry Andric // registers. 736*0fca6ea1SDimitry Andric unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = nullptr) { 737*0fca6ea1SDimitry Andric RegUnit &RU = RegUnits.emplace_back(); 738*0fca6ea1SDimitry Andric RU.Roots[0] = R0; 739*0fca6ea1SDimitry Andric RU.Roots[1] = R1; 740*0fca6ea1SDimitry Andric RU.Artificial = R0->Artificial; 741*0fca6ea1SDimitry Andric if (R1) 742*0fca6ea1SDimitry Andric RU.Artificial |= R1->Artificial; 743*0fca6ea1SDimitry Andric return RegUnits.size() - 1; 744*0fca6ea1SDimitry Andric } 745*0fca6ea1SDimitry Andric 746*0fca6ea1SDimitry Andric // Create a new non-native register unit that can be adopted by a register 747*0fca6ea1SDimitry Andric // to increase its pressure. Note that NumNativeRegUnits is not increased. 748*0fca6ea1SDimitry Andric unsigned newRegUnit(unsigned Weight) { 749*0fca6ea1SDimitry Andric RegUnit &RU = RegUnits.emplace_back(); 750*0fca6ea1SDimitry Andric RU.Weight = Weight; 751*0fca6ea1SDimitry Andric return RegUnits.size() - 1; 752*0fca6ea1SDimitry Andric } 753*0fca6ea1SDimitry Andric 754*0fca6ea1SDimitry Andric // Native units are the singular unit of a leaf register. Register aliasing 755*0fca6ea1SDimitry Andric // is completely characterized by native units. Adopted units exist to give 756*0fca6ea1SDimitry Andric // register additional weight but don't affect aliasing. 757*0fca6ea1SDimitry Andric bool isNativeUnit(unsigned RUID) const { return RUID < NumNativeRegUnits; } 758*0fca6ea1SDimitry Andric 759*0fca6ea1SDimitry Andric unsigned getNumNativeRegUnits() const { return NumNativeRegUnits; } 760*0fca6ea1SDimitry Andric 761*0fca6ea1SDimitry Andric RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; } 762*0fca6ea1SDimitry Andric const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; } 763*0fca6ea1SDimitry Andric 764*0fca6ea1SDimitry Andric std::list<CodeGenRegisterClass> &getRegClasses() { return RegClasses; } 765*0fca6ea1SDimitry Andric 766*0fca6ea1SDimitry Andric const std::list<CodeGenRegisterClass> &getRegClasses() const { 767*0fca6ea1SDimitry Andric return RegClasses; 768*0fca6ea1SDimitry Andric } 769*0fca6ea1SDimitry Andric 770*0fca6ea1SDimitry Andric std::list<CodeGenRegisterCategory> &getRegCategories() { 771*0fca6ea1SDimitry Andric return RegCategories; 772*0fca6ea1SDimitry Andric } 773*0fca6ea1SDimitry Andric 774*0fca6ea1SDimitry Andric const std::list<CodeGenRegisterCategory> &getRegCategories() const { 775*0fca6ea1SDimitry Andric return RegCategories; 776*0fca6ea1SDimitry Andric } 777*0fca6ea1SDimitry Andric 778*0fca6ea1SDimitry Andric // Find a register class from its def. 779*0fca6ea1SDimitry Andric CodeGenRegisterClass *getRegClass(const Record *) const; 780*0fca6ea1SDimitry Andric 781*0fca6ea1SDimitry Andric /// getRegisterClassForRegister - Find the register class that contains the 782*0fca6ea1SDimitry Andric /// specified physical register. If the register is not in a register 783*0fca6ea1SDimitry Andric /// class, return null. If the register is in multiple classes, and the 784*0fca6ea1SDimitry Andric /// classes have a superset-subset relationship and the same set of types, 785*0fca6ea1SDimitry Andric /// return the superclass. Otherwise return null. 786*0fca6ea1SDimitry Andric const CodeGenRegisterClass *getRegClassForRegister(Record *R); 787*0fca6ea1SDimitry Andric 788*0fca6ea1SDimitry Andric // Analog of TargetRegisterInfo::getMinimalPhysRegClass. Unlike 789*0fca6ea1SDimitry Andric // getRegClassForRegister, this tries to find the smallest class containing 790*0fca6ea1SDimitry Andric // the physical register. If \p VT is specified, it will only find classes 791*0fca6ea1SDimitry Andric // with a matching type 792*0fca6ea1SDimitry Andric const CodeGenRegisterClass * 793*0fca6ea1SDimitry Andric getMinimalPhysRegClass(Record *RegRecord, ValueTypeByHwMode *VT = nullptr); 794*0fca6ea1SDimitry Andric 795*0fca6ea1SDimitry Andric // Get the sum of unit weights. 796*0fca6ea1SDimitry Andric unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const { 797*0fca6ea1SDimitry Andric unsigned Weight = 0; 798*0fca6ea1SDimitry Andric for (unsigned Unit : Units) 799*0fca6ea1SDimitry Andric Weight += getRegUnit(Unit).Weight; 800*0fca6ea1SDimitry Andric return Weight; 801*0fca6ea1SDimitry Andric } 802*0fca6ea1SDimitry Andric 803*0fca6ea1SDimitry Andric unsigned getRegSetIDAt(unsigned Order) const { 804*0fca6ea1SDimitry Andric return RegUnitSetOrder[Order]; 805*0fca6ea1SDimitry Andric } 806*0fca6ea1SDimitry Andric 807*0fca6ea1SDimitry Andric const RegUnitSet &getRegSetAt(unsigned Order) const { 808*0fca6ea1SDimitry Andric return RegUnitSets[RegUnitSetOrder[Order]]; 809*0fca6ea1SDimitry Andric } 810*0fca6ea1SDimitry Andric 811*0fca6ea1SDimitry Andric // Increase a RegUnitWeight. 812*0fca6ea1SDimitry Andric void increaseRegUnitWeight(unsigned RUID, unsigned Inc) { 813*0fca6ea1SDimitry Andric getRegUnit(RUID).Weight += Inc; 814*0fca6ea1SDimitry Andric } 815*0fca6ea1SDimitry Andric 816*0fca6ea1SDimitry Andric // Get the number of register pressure dimensions. 817*0fca6ea1SDimitry Andric unsigned getNumRegPressureSets() const { return RegUnitSets.size(); } 818*0fca6ea1SDimitry Andric 819*0fca6ea1SDimitry Andric // Get a set of register unit IDs for a given dimension of pressure. 820*0fca6ea1SDimitry Andric const RegUnitSet &getRegPressureSet(unsigned Idx) const { 821*0fca6ea1SDimitry Andric return RegUnitSets[Idx]; 822*0fca6ea1SDimitry Andric } 823*0fca6ea1SDimitry Andric 824*0fca6ea1SDimitry Andric // The number of pressure set lists may be larget than the number of 825*0fca6ea1SDimitry Andric // register classes if some register units appeared in a list of sets that 826*0fca6ea1SDimitry Andric // did not correspond to an existing register class. 827*0fca6ea1SDimitry Andric unsigned getNumRegClassPressureSetLists() const { 828*0fca6ea1SDimitry Andric return RegClassUnitSets.size(); 829*0fca6ea1SDimitry Andric } 830*0fca6ea1SDimitry Andric 831*0fca6ea1SDimitry Andric // Get a list of pressure set IDs for a register class. Liveness of a 832*0fca6ea1SDimitry Andric // register in this class impacts each pressure set in this list by the 833*0fca6ea1SDimitry Andric // weight of the register. An exact solution requires all registers in a 834*0fca6ea1SDimitry Andric // class to have the same class, but it is not strictly guaranteed. 835*0fca6ea1SDimitry Andric ArrayRef<unsigned> getRCPressureSetIDs(unsigned RCIdx) const { 836*0fca6ea1SDimitry Andric return RegClassUnitSets[RCIdx]; 837*0fca6ea1SDimitry Andric } 838*0fca6ea1SDimitry Andric 839*0fca6ea1SDimitry Andric // Computed derived records such as missing sub-register indices. 840*0fca6ea1SDimitry Andric void computeDerivedInfo(); 841*0fca6ea1SDimitry Andric 842*0fca6ea1SDimitry Andric // Compute the set of registers completely covered by the registers in Regs. 843*0fca6ea1SDimitry Andric // The returned BitVector will have a bit set for each register in Regs, 844*0fca6ea1SDimitry Andric // all sub-registers, and all super-registers that are covered by the 845*0fca6ea1SDimitry Andric // registers in Regs. 846*0fca6ea1SDimitry Andric // 847*0fca6ea1SDimitry Andric // This is used to compute the mask of call-preserved registers from a list 848*0fca6ea1SDimitry Andric // of callee-saves. 849*0fca6ea1SDimitry Andric BitVector computeCoveredRegisters(ArrayRef<Record *> Regs); 850*0fca6ea1SDimitry Andric 851*0fca6ea1SDimitry Andric // Bit mask of lanes that cover their registers. A sub-register index whose 852*0fca6ea1SDimitry Andric // LaneMask is contained in CoveringLanes will be completely covered by 853*0fca6ea1SDimitry Andric // another sub-register with the same or larger lane mask. 854*0fca6ea1SDimitry Andric LaneBitmask CoveringLanes; 855*0fca6ea1SDimitry Andric 856*0fca6ea1SDimitry Andric // Helper function for printing debug information. Handles artificial 857*0fca6ea1SDimitry Andric // (non-native) reg units. 858*0fca6ea1SDimitry Andric void printRegUnitName(unsigned Unit) const; 859*0fca6ea1SDimitry Andric }; 860*0fca6ea1SDimitry Andric 861*0fca6ea1SDimitry Andric } // end namespace llvm 862*0fca6ea1SDimitry Andric 863*0fca6ea1SDimitry Andric #endif // LLVM_UTILS_TABLEGEN_CODEGENREGISTERS_H 864