106f32e7eSjoerg //===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg // 906f32e7eSjoerg // This file defines structures to encapsulate information gleaned from the 1006f32e7eSjoerg // target register and register class definitions. 1106f32e7eSjoerg // 1206f32e7eSjoerg //===----------------------------------------------------------------------===// 1306f32e7eSjoerg 1406f32e7eSjoerg #ifndef LLVM_UTILS_TABLEGEN_CODEGENREGISTERS_H 1506f32e7eSjoerg #define LLVM_UTILS_TABLEGEN_CODEGENREGISTERS_H 1606f32e7eSjoerg 1706f32e7eSjoerg #include "InfoByHwMode.h" 1806f32e7eSjoerg #include "llvm/ADT/ArrayRef.h" 1906f32e7eSjoerg #include "llvm/ADT/BitVector.h" 2006f32e7eSjoerg #include "llvm/ADT/DenseMap.h" 2106f32e7eSjoerg #include "llvm/ADT/STLExtras.h" 2206f32e7eSjoerg #include "llvm/ADT/SetVector.h" 2306f32e7eSjoerg #include "llvm/ADT/SmallPtrSet.h" 2406f32e7eSjoerg #include "llvm/ADT/SmallVector.h" 2506f32e7eSjoerg #include "llvm/ADT/SparseBitVector.h" 2606f32e7eSjoerg #include "llvm/ADT/StringMap.h" 2706f32e7eSjoerg #include "llvm/ADT/StringRef.h" 2806f32e7eSjoerg #include "llvm/MC/LaneBitmask.h" 2906f32e7eSjoerg #include "llvm/Support/ErrorHandling.h" 3006f32e7eSjoerg #include "llvm/Support/MachineValueType.h" 3106f32e7eSjoerg #include "llvm/TableGen/Record.h" 3206f32e7eSjoerg #include "llvm/TableGen/SetTheory.h" 3306f32e7eSjoerg #include <cassert> 3406f32e7eSjoerg #include <cstdint> 3506f32e7eSjoerg #include <deque> 3606f32e7eSjoerg #include <list> 3706f32e7eSjoerg #include <map> 3806f32e7eSjoerg #include <string> 3906f32e7eSjoerg #include <utility> 4006f32e7eSjoerg #include <vector> 4106f32e7eSjoerg 4206f32e7eSjoerg namespace llvm { 4306f32e7eSjoerg 4406f32e7eSjoerg class CodeGenRegBank; 4506f32e7eSjoerg template <typename T, typename Vector, typename Set> class SetVector; 4606f32e7eSjoerg 4706f32e7eSjoerg /// Used to encode a step in a register lane mask transformation. 4806f32e7eSjoerg /// Mask the bits specified in Mask, then rotate them Rol bits to the left 4906f32e7eSjoerg /// assuming a wraparound at 32bits. 5006f32e7eSjoerg struct MaskRolPair { 5106f32e7eSjoerg LaneBitmask Mask; 5206f32e7eSjoerg uint8_t RotateLeft; 5306f32e7eSjoerg 5406f32e7eSjoerg bool operator==(const MaskRolPair Other) const { 5506f32e7eSjoerg return Mask == Other.Mask && RotateLeft == Other.RotateLeft; 5606f32e7eSjoerg } 5706f32e7eSjoerg bool operator!=(const MaskRolPair Other) const { 5806f32e7eSjoerg return Mask != Other.Mask || RotateLeft != Other.RotateLeft; 5906f32e7eSjoerg } 6006f32e7eSjoerg }; 6106f32e7eSjoerg 6206f32e7eSjoerg /// CodeGenSubRegIndex - Represents a sub-register index. 6306f32e7eSjoerg class CodeGenSubRegIndex { 6406f32e7eSjoerg Record *const TheDef; 6506f32e7eSjoerg std::string Name; 6606f32e7eSjoerg std::string Namespace; 6706f32e7eSjoerg 6806f32e7eSjoerg public: 6906f32e7eSjoerg uint16_t Size; 7006f32e7eSjoerg uint16_t Offset; 7106f32e7eSjoerg const unsigned EnumValue; 7206f32e7eSjoerg mutable LaneBitmask LaneMask; 7306f32e7eSjoerg mutable SmallVector<MaskRolPair,1> CompositionLaneMaskTransform; 7406f32e7eSjoerg 7506f32e7eSjoerg /// A list of subregister indexes concatenated resulting in this 7606f32e7eSjoerg /// subregister index. This is the reverse of CodeGenRegBank::ConcatIdx. 7706f32e7eSjoerg SmallVector<CodeGenSubRegIndex*,4> ConcatenationOf; 7806f32e7eSjoerg 7906f32e7eSjoerg // Are all super-registers containing this SubRegIndex covered by their 8006f32e7eSjoerg // sub-registers? 8106f32e7eSjoerg bool AllSuperRegsCovered; 8206f32e7eSjoerg // A subregister index is "artificial" if every subregister obtained 8306f32e7eSjoerg // from applying this index is artificial. Artificial subregister 8406f32e7eSjoerg // indexes are not used to create new register classes. 8506f32e7eSjoerg bool Artificial; 8606f32e7eSjoerg 8706f32e7eSjoerg CodeGenSubRegIndex(Record *R, unsigned Enum); 8806f32e7eSjoerg CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum); 89*da58b97aSjoerg CodeGenSubRegIndex(CodeGenSubRegIndex&) = delete; 9006f32e7eSjoerg getName()9106f32e7eSjoerg const std::string &getName() const { return Name; } getNamespace()9206f32e7eSjoerg const std::string &getNamespace() const { return Namespace; } 9306f32e7eSjoerg std::string getQualifiedName() const; 9406f32e7eSjoerg 9506f32e7eSjoerg // Map of composite subreg indices. 9606f32e7eSjoerg typedef std::map<CodeGenSubRegIndex *, CodeGenSubRegIndex *, 9706f32e7eSjoerg deref<std::less<>>> 9806f32e7eSjoerg CompMap; 9906f32e7eSjoerg 10006f32e7eSjoerg // Returns the subreg index that results from composing this with Idx. 10106f32e7eSjoerg // Returns NULL if this and Idx don't compose. compose(CodeGenSubRegIndex * Idx)10206f32e7eSjoerg CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const { 10306f32e7eSjoerg CompMap::const_iterator I = Composed.find(Idx); 10406f32e7eSjoerg return I == Composed.end() ? nullptr : I->second; 10506f32e7eSjoerg } 10606f32e7eSjoerg 10706f32e7eSjoerg // Add a composite subreg index: this+A = B. 10806f32e7eSjoerg // Return a conflicting composite, or NULL addComposite(CodeGenSubRegIndex * A,CodeGenSubRegIndex * B)10906f32e7eSjoerg CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, 11006f32e7eSjoerg CodeGenSubRegIndex *B) { 11106f32e7eSjoerg assert(A && B); 11206f32e7eSjoerg std::pair<CompMap::iterator, bool> Ins = 11306f32e7eSjoerg Composed.insert(std::make_pair(A, B)); 11406f32e7eSjoerg // Synthetic subreg indices that aren't contiguous (for instance ARM 11506f32e7eSjoerg // register tuples) don't have a bit range, so it's OK to let 11606f32e7eSjoerg // B->Offset == -1. For the other cases, accumulate the offset and set 11706f32e7eSjoerg // the size here. Only do so if there is no offset yet though. 11806f32e7eSjoerg if ((Offset != (uint16_t)-1 && A->Offset != (uint16_t)-1) && 11906f32e7eSjoerg (B->Offset == (uint16_t)-1)) { 12006f32e7eSjoerg B->Offset = Offset + A->Offset; 12106f32e7eSjoerg B->Size = A->Size; 12206f32e7eSjoerg } 12306f32e7eSjoerg return (Ins.second || Ins.first->second == B) ? nullptr 12406f32e7eSjoerg : Ins.first->second; 12506f32e7eSjoerg } 12606f32e7eSjoerg 12706f32e7eSjoerg // Update the composite maps of components specified in 'ComposedOf'. 12806f32e7eSjoerg void updateComponents(CodeGenRegBank&); 12906f32e7eSjoerg 13006f32e7eSjoerg // Return the map of composites. getComposites()13106f32e7eSjoerg const CompMap &getComposites() const { return Composed; } 13206f32e7eSjoerg 13306f32e7eSjoerg // Compute LaneMask from Composed. Return LaneMask. 13406f32e7eSjoerg LaneBitmask computeLaneMask() const; 13506f32e7eSjoerg 13606f32e7eSjoerg void setConcatenationOf(ArrayRef<CodeGenSubRegIndex*> Parts); 13706f32e7eSjoerg 13806f32e7eSjoerg /// Replaces subregister indexes in the `ConcatenationOf` list with 13906f32e7eSjoerg /// list of subregisters they are composed of (if any). Do this recursively. 14006f32e7eSjoerg void computeConcatTransitiveClosure(); 14106f32e7eSjoerg 14206f32e7eSjoerg bool operator<(const CodeGenSubRegIndex &RHS) const { 14306f32e7eSjoerg return this->EnumValue < RHS.EnumValue; 14406f32e7eSjoerg } 14506f32e7eSjoerg 14606f32e7eSjoerg private: 14706f32e7eSjoerg CompMap Composed; 14806f32e7eSjoerg }; 14906f32e7eSjoerg 15006f32e7eSjoerg /// CodeGenRegister - Represents a register definition. 15106f32e7eSjoerg struct CodeGenRegister { 15206f32e7eSjoerg Record *TheDef; 15306f32e7eSjoerg unsigned EnumValue; 154*da58b97aSjoerg std::vector<int64_t> CostPerUse; 15506f32e7eSjoerg bool CoveredBySubRegs; 15606f32e7eSjoerg bool HasDisjunctSubRegs; 15706f32e7eSjoerg bool Artificial; 15806f32e7eSjoerg 15906f32e7eSjoerg // Map SubRegIndex -> Register. 16006f32e7eSjoerg typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, 16106f32e7eSjoerg deref<std::less<>>> 16206f32e7eSjoerg SubRegMap; 16306f32e7eSjoerg 16406f32e7eSjoerg CodeGenRegister(Record *R, unsigned Enum); 16506f32e7eSjoerg 166*da58b97aSjoerg StringRef getName() const; 16706f32e7eSjoerg 16806f32e7eSjoerg // Extract more information from TheDef. This is used to build an object 16906f32e7eSjoerg // graph after all CodeGenRegister objects have been created. 17006f32e7eSjoerg void buildObjectGraph(CodeGenRegBank&); 17106f32e7eSjoerg 17206f32e7eSjoerg // Lazily compute a map of all sub-registers. 17306f32e7eSjoerg // This includes unique entries for all sub-sub-registers. 17406f32e7eSjoerg const SubRegMap &computeSubRegs(CodeGenRegBank&); 17506f32e7eSjoerg 17606f32e7eSjoerg // Compute extra sub-registers by combining the existing sub-registers. 17706f32e7eSjoerg void computeSecondarySubRegs(CodeGenRegBank&); 17806f32e7eSjoerg 17906f32e7eSjoerg // Add this as a super-register to all sub-registers after the sub-register 18006f32e7eSjoerg // graph has been built. 18106f32e7eSjoerg void computeSuperRegs(CodeGenRegBank&); 18206f32e7eSjoerg getSubRegsCodeGenRegister18306f32e7eSjoerg const SubRegMap &getSubRegs() const { 18406f32e7eSjoerg assert(SubRegsComplete && "Must precompute sub-registers"); 18506f32e7eSjoerg return SubRegs; 18606f32e7eSjoerg } 18706f32e7eSjoerg 18806f32e7eSjoerg // Add sub-registers to OSet following a pre-order defined by the .td file. 18906f32e7eSjoerg void addSubRegsPreOrder(SetVector<const CodeGenRegister*> &OSet, 19006f32e7eSjoerg CodeGenRegBank&) const; 19106f32e7eSjoerg 19206f32e7eSjoerg // Return the sub-register index naming Reg as a sub-register of this 19306f32e7eSjoerg // register. Returns NULL if Reg is not a sub-register. getSubRegIndexCodeGenRegister19406f32e7eSjoerg CodeGenSubRegIndex *getSubRegIndex(const CodeGenRegister *Reg) const { 19506f32e7eSjoerg return SubReg2Idx.lookup(Reg); 19606f32e7eSjoerg } 19706f32e7eSjoerg 19806f32e7eSjoerg typedef std::vector<const CodeGenRegister*> SuperRegList; 19906f32e7eSjoerg 20006f32e7eSjoerg // Get the list of super-registers in topological order, small to large. 20106f32e7eSjoerg // This is valid after computeSubRegs visits all registers during RegBank 20206f32e7eSjoerg // construction. getSuperRegsCodeGenRegister20306f32e7eSjoerg const SuperRegList &getSuperRegs() const { 20406f32e7eSjoerg assert(SubRegsComplete && "Must precompute sub-registers"); 20506f32e7eSjoerg return SuperRegs; 20606f32e7eSjoerg } 20706f32e7eSjoerg 20806f32e7eSjoerg // Get the list of ad hoc aliases. The graph is symmetric, so the list 20906f32e7eSjoerg // contains all registers in 'Aliases', and all registers that mention this 21006f32e7eSjoerg // register in 'Aliases'. getExplicitAliasesCodeGenRegister21106f32e7eSjoerg ArrayRef<CodeGenRegister*> getExplicitAliases() const { 21206f32e7eSjoerg return ExplicitAliases; 21306f32e7eSjoerg } 21406f32e7eSjoerg 21506f32e7eSjoerg // Get the topological signature of this register. This is a small integer 21606f32e7eSjoerg // less than RegBank.getNumTopoSigs(). Registers with the same TopoSig have 21706f32e7eSjoerg // identical sub-register structure. That is, they support the same set of 21806f32e7eSjoerg // sub-register indices mapping to the same kind of sub-registers 21906f32e7eSjoerg // (TopoSig-wise). getTopoSigCodeGenRegister22006f32e7eSjoerg unsigned getTopoSig() const { 22106f32e7eSjoerg assert(SuperRegsComplete && "TopoSigs haven't been computed yet."); 22206f32e7eSjoerg return TopoSig; 22306f32e7eSjoerg } 22406f32e7eSjoerg 22506f32e7eSjoerg // List of register units in ascending order. 22606f32e7eSjoerg typedef SparseBitVector<> RegUnitList; 22706f32e7eSjoerg typedef SmallVector<LaneBitmask, 16> RegUnitLaneMaskList; 22806f32e7eSjoerg 22906f32e7eSjoerg // How many entries in RegUnitList are native? 23006f32e7eSjoerg RegUnitList NativeRegUnits; 23106f32e7eSjoerg 23206f32e7eSjoerg // Get the list of register units. 23306f32e7eSjoerg // This is only valid after computeSubRegs() completes. getRegUnitsCodeGenRegister23406f32e7eSjoerg const RegUnitList &getRegUnits() const { return RegUnits; } 23506f32e7eSjoerg getRegUnitLaneMasksCodeGenRegister23606f32e7eSjoerg ArrayRef<LaneBitmask> getRegUnitLaneMasks() const { 23706f32e7eSjoerg return makeArrayRef(RegUnitLaneMasks).slice(0, NativeRegUnits.count()); 23806f32e7eSjoerg } 23906f32e7eSjoerg 24006f32e7eSjoerg // Get the native register units. This is a prefix of getRegUnits(). getNativeRegUnitsCodeGenRegister24106f32e7eSjoerg RegUnitList getNativeRegUnits() const { 24206f32e7eSjoerg return NativeRegUnits; 24306f32e7eSjoerg } 24406f32e7eSjoerg setRegUnitLaneMasksCodeGenRegister24506f32e7eSjoerg void setRegUnitLaneMasks(const RegUnitLaneMaskList &LaneMasks) { 24606f32e7eSjoerg RegUnitLaneMasks = LaneMasks; 24706f32e7eSjoerg } 24806f32e7eSjoerg 24906f32e7eSjoerg // Inherit register units from subregisters. 25006f32e7eSjoerg // Return true if the RegUnits changed. 25106f32e7eSjoerg bool inheritRegUnits(CodeGenRegBank &RegBank); 25206f32e7eSjoerg 25306f32e7eSjoerg // Adopt a register unit for pressure tracking. 25406f32e7eSjoerg // A unit is adopted iff its unit number is >= NativeRegUnits.count(). adoptRegUnitCodeGenRegister25506f32e7eSjoerg void adoptRegUnit(unsigned RUID) { RegUnits.set(RUID); } 25606f32e7eSjoerg 25706f32e7eSjoerg // Get the sum of this register's register unit weights. 25806f32e7eSjoerg unsigned getWeight(const CodeGenRegBank &RegBank) const; 25906f32e7eSjoerg 26006f32e7eSjoerg // Canonically ordered set. 26106f32e7eSjoerg typedef std::vector<const CodeGenRegister*> Vec; 26206f32e7eSjoerg 26306f32e7eSjoerg private: 26406f32e7eSjoerg bool SubRegsComplete; 26506f32e7eSjoerg bool SuperRegsComplete; 26606f32e7eSjoerg unsigned TopoSig; 26706f32e7eSjoerg 26806f32e7eSjoerg // The sub-registers explicit in the .td file form a tree. 26906f32e7eSjoerg SmallVector<CodeGenSubRegIndex*, 8> ExplicitSubRegIndices; 27006f32e7eSjoerg SmallVector<CodeGenRegister*, 8> ExplicitSubRegs; 27106f32e7eSjoerg 27206f32e7eSjoerg // Explicit ad hoc aliases, symmetrized to form an undirected graph. 27306f32e7eSjoerg SmallVector<CodeGenRegister*, 8> ExplicitAliases; 27406f32e7eSjoerg 27506f32e7eSjoerg // Super-registers where this is the first explicit sub-register. 27606f32e7eSjoerg SuperRegList LeadingSuperRegs; 27706f32e7eSjoerg 27806f32e7eSjoerg SubRegMap SubRegs; 27906f32e7eSjoerg SuperRegList SuperRegs; 28006f32e7eSjoerg DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*> SubReg2Idx; 28106f32e7eSjoerg RegUnitList RegUnits; 28206f32e7eSjoerg RegUnitLaneMaskList RegUnitLaneMasks; 28306f32e7eSjoerg }; 28406f32e7eSjoerg 28506f32e7eSjoerg inline bool operator<(const CodeGenRegister &A, const CodeGenRegister &B) { 28606f32e7eSjoerg return A.EnumValue < B.EnumValue; 28706f32e7eSjoerg } 28806f32e7eSjoerg 28906f32e7eSjoerg inline bool operator==(const CodeGenRegister &A, const CodeGenRegister &B) { 29006f32e7eSjoerg return A.EnumValue == B.EnumValue; 29106f32e7eSjoerg } 29206f32e7eSjoerg 29306f32e7eSjoerg class CodeGenRegisterClass { 29406f32e7eSjoerg CodeGenRegister::Vec Members; 29506f32e7eSjoerg // Allocation orders. Order[0] always contains all registers in Members. 29606f32e7eSjoerg std::vector<SmallVector<Record*, 16>> Orders; 29706f32e7eSjoerg // Bit mask of sub-classes including this, indexed by their EnumValue. 29806f32e7eSjoerg BitVector SubClasses; 29906f32e7eSjoerg // List of super-classes, topologocally ordered to have the larger classes 30006f32e7eSjoerg // first. This is the same as sorting by EnumValue. 30106f32e7eSjoerg SmallVector<CodeGenRegisterClass*, 4> SuperClasses; 30206f32e7eSjoerg Record *TheDef; 30306f32e7eSjoerg std::string Name; 30406f32e7eSjoerg 30506f32e7eSjoerg // For a synthesized class, inherit missing properties from the nearest 30606f32e7eSjoerg // super-class. 30706f32e7eSjoerg void inheritProperties(CodeGenRegBank&); 30806f32e7eSjoerg 30906f32e7eSjoerg // Map SubRegIndex -> sub-class. This is the largest sub-class where all 31006f32e7eSjoerg // registers have a SubRegIndex sub-register. 31106f32e7eSjoerg DenseMap<const CodeGenSubRegIndex *, CodeGenRegisterClass *> 31206f32e7eSjoerg SubClassWithSubReg; 31306f32e7eSjoerg 31406f32e7eSjoerg // Map SubRegIndex -> set of super-reg classes. This is all register 31506f32e7eSjoerg // classes SuperRC such that: 31606f32e7eSjoerg // 31706f32e7eSjoerg // R:SubRegIndex in this RC for all R in SuperRC. 31806f32e7eSjoerg // 31906f32e7eSjoerg DenseMap<const CodeGenSubRegIndex *, SmallPtrSet<CodeGenRegisterClass *, 8>> 32006f32e7eSjoerg SuperRegClasses; 32106f32e7eSjoerg 32206f32e7eSjoerg // Bit vector of TopoSigs for the registers in this class. This will be 32306f32e7eSjoerg // very sparse on regular architectures. 32406f32e7eSjoerg BitVector TopoSigs; 32506f32e7eSjoerg 32606f32e7eSjoerg public: 32706f32e7eSjoerg unsigned EnumValue; 32806f32e7eSjoerg StringRef Namespace; 32906f32e7eSjoerg SmallVector<ValueTypeByHwMode, 4> VTs; 33006f32e7eSjoerg RegSizeInfoByHwMode RSI; 33106f32e7eSjoerg int CopyCost; 33206f32e7eSjoerg bool Allocatable; 33306f32e7eSjoerg StringRef AltOrderSelect; 33406f32e7eSjoerg uint8_t AllocationPriority; 33506f32e7eSjoerg /// Contains the combination of the lane masks of all subregisters. 33606f32e7eSjoerg LaneBitmask LaneMask; 33706f32e7eSjoerg /// True if there are at least 2 subregisters which do not interfere. 33806f32e7eSjoerg bool HasDisjunctSubRegs; 33906f32e7eSjoerg bool CoveredBySubRegs; 34006f32e7eSjoerg /// A register class is artificial if all its members are artificial. 34106f32e7eSjoerg bool Artificial; 342*da58b97aSjoerg /// Generate register pressure set for this register class and any class 343*da58b97aSjoerg /// synthesized from it. 344*da58b97aSjoerg bool GeneratePressureSet; 34506f32e7eSjoerg 34606f32e7eSjoerg // Return the Record that defined this class, or NULL if the class was 34706f32e7eSjoerg // created by TableGen. getDef()34806f32e7eSjoerg Record *getDef() const { return TheDef; } 34906f32e7eSjoerg getName()35006f32e7eSjoerg const std::string &getName() const { return Name; } 35106f32e7eSjoerg std::string getQualifiedName() const; getValueTypes()35206f32e7eSjoerg ArrayRef<ValueTypeByHwMode> getValueTypes() const { return VTs; } getNumValueTypes()35306f32e7eSjoerg unsigned getNumValueTypes() const { return VTs.size(); } 35406f32e7eSjoerg hasType(const ValueTypeByHwMode & VT)35506f32e7eSjoerg bool hasType(const ValueTypeByHwMode &VT) const { 356*da58b97aSjoerg return llvm::is_contained(VTs, VT); 35706f32e7eSjoerg } 35806f32e7eSjoerg getValueTypeNum(unsigned VTNum)35906f32e7eSjoerg const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const { 36006f32e7eSjoerg if (VTNum < VTs.size()) 36106f32e7eSjoerg return VTs[VTNum]; 36206f32e7eSjoerg llvm_unreachable("VTNum greater than number of ValueTypes in RegClass!"); 36306f32e7eSjoerg } 36406f32e7eSjoerg 36506f32e7eSjoerg // Return true if this this class contains the register. 36606f32e7eSjoerg bool contains(const CodeGenRegister*) const; 36706f32e7eSjoerg 36806f32e7eSjoerg // Returns true if RC is a subclass. 36906f32e7eSjoerg // RC is a sub-class of this class if it is a valid replacement for any 37006f32e7eSjoerg // instruction operand where a register of this classis required. It must 37106f32e7eSjoerg // satisfy these conditions: 37206f32e7eSjoerg // 37306f32e7eSjoerg // 1. All RC registers are also in this. 37406f32e7eSjoerg // 2. The RC spill size must not be smaller than our spill size. 37506f32e7eSjoerg // 3. RC spill alignment must be compatible with ours. 37606f32e7eSjoerg // hasSubClass(const CodeGenRegisterClass * RC)37706f32e7eSjoerg bool hasSubClass(const CodeGenRegisterClass *RC) const { 37806f32e7eSjoerg return SubClasses.test(RC->EnumValue); 37906f32e7eSjoerg } 38006f32e7eSjoerg 38106f32e7eSjoerg // getSubClassWithSubReg - Returns the largest sub-class where all 38206f32e7eSjoerg // registers have a SubIdx sub-register. 38306f32e7eSjoerg CodeGenRegisterClass * getSubClassWithSubReg(const CodeGenSubRegIndex * SubIdx)38406f32e7eSjoerg getSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx) const { 38506f32e7eSjoerg return SubClassWithSubReg.lookup(SubIdx); 38606f32e7eSjoerg } 38706f32e7eSjoerg 38806f32e7eSjoerg /// Find largest subclass where all registers have SubIdx subregisters in 38906f32e7eSjoerg /// SubRegClass and the largest subregister class that contains those 39006f32e7eSjoerg /// subregisters without (as far as possible) also containing additional registers. 39106f32e7eSjoerg /// 39206f32e7eSjoerg /// This can be used to find a suitable pair of classes for subregister copies. 39306f32e7eSjoerg /// \return std::pair<SubClass, SubRegClass> where SubClass is a SubClass is 39406f32e7eSjoerg /// a class where every register has SubIdx and SubRegClass is a class where 39506f32e7eSjoerg /// every register is covered by the SubIdx subregister of SubClass. 39606f32e7eSjoerg Optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>> 39706f32e7eSjoerg getMatchingSubClassWithSubRegs(CodeGenRegBank &RegBank, 39806f32e7eSjoerg const CodeGenSubRegIndex *SubIdx) const; 39906f32e7eSjoerg setSubClassWithSubReg(const CodeGenSubRegIndex * SubIdx,CodeGenRegisterClass * SubRC)40006f32e7eSjoerg void setSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx, 40106f32e7eSjoerg CodeGenRegisterClass *SubRC) { 40206f32e7eSjoerg SubClassWithSubReg[SubIdx] = SubRC; 40306f32e7eSjoerg } 40406f32e7eSjoerg 40506f32e7eSjoerg // getSuperRegClasses - Returns a bit vector of all register classes 40606f32e7eSjoerg // containing only SubIdx super-registers of this class. 40706f32e7eSjoerg void getSuperRegClasses(const CodeGenSubRegIndex *SubIdx, 40806f32e7eSjoerg BitVector &Out) const; 40906f32e7eSjoerg 41006f32e7eSjoerg // addSuperRegClass - Add a class containing only SubIdx super-registers. addSuperRegClass(CodeGenSubRegIndex * SubIdx,CodeGenRegisterClass * SuperRC)41106f32e7eSjoerg void addSuperRegClass(CodeGenSubRegIndex *SubIdx, 41206f32e7eSjoerg CodeGenRegisterClass *SuperRC) { 41306f32e7eSjoerg SuperRegClasses[SubIdx].insert(SuperRC); 41406f32e7eSjoerg } 41506f32e7eSjoerg 41606f32e7eSjoerg // getSubClasses - Returns a constant BitVector of subclasses indexed by 41706f32e7eSjoerg // EnumValue. 41806f32e7eSjoerg // The SubClasses vector includes an entry for this class. getSubClasses()41906f32e7eSjoerg const BitVector &getSubClasses() const { return SubClasses; } 42006f32e7eSjoerg 42106f32e7eSjoerg // getSuperClasses - Returns a list of super classes ordered by EnumValue. 42206f32e7eSjoerg // The array does not include an entry for this class. getSuperClasses()42306f32e7eSjoerg ArrayRef<CodeGenRegisterClass*> getSuperClasses() const { 42406f32e7eSjoerg return SuperClasses; 42506f32e7eSjoerg } 42606f32e7eSjoerg 42706f32e7eSjoerg // Returns an ordered list of class members. 42806f32e7eSjoerg // The order of registers is the same as in the .td file. 42906f32e7eSjoerg // No = 0 is the default allocation order, No = 1 is the first alternative. 43006f32e7eSjoerg ArrayRef<Record*> getOrder(unsigned No = 0) const { 43106f32e7eSjoerg return Orders[No]; 43206f32e7eSjoerg } 43306f32e7eSjoerg 43406f32e7eSjoerg // Return the total number of allocation orders available. getNumOrders()43506f32e7eSjoerg unsigned getNumOrders() const { return Orders.size(); } 43606f32e7eSjoerg 43706f32e7eSjoerg // Get the set of registers. This set contains the same registers as 43806f32e7eSjoerg // getOrder(0). getMembers()43906f32e7eSjoerg const CodeGenRegister::Vec &getMembers() const { return Members; } 44006f32e7eSjoerg 44106f32e7eSjoerg // Get a bit vector of TopoSigs present in this register class. getTopoSigs()44206f32e7eSjoerg const BitVector &getTopoSigs() const { return TopoSigs; } 44306f32e7eSjoerg 444*da58b97aSjoerg // Get a weight of this register class. 445*da58b97aSjoerg unsigned getWeight(const CodeGenRegBank&) const; 446*da58b97aSjoerg 44706f32e7eSjoerg // Populate a unique sorted list of units from a register set. 44806f32e7eSjoerg void buildRegUnitSet(const CodeGenRegBank &RegBank, 44906f32e7eSjoerg std::vector<unsigned> &RegUnits) const; 45006f32e7eSjoerg 45106f32e7eSjoerg CodeGenRegisterClass(CodeGenRegBank&, Record *R); 452*da58b97aSjoerg CodeGenRegisterClass(CodeGenRegisterClass&) = delete; 45306f32e7eSjoerg 45406f32e7eSjoerg // A key representing the parts of a register class used for forming 45506f32e7eSjoerg // sub-classes. Note the ordering provided by this key is not the same as 45606f32e7eSjoerg // the topological order used for the EnumValues. 45706f32e7eSjoerg struct Key { 45806f32e7eSjoerg const CodeGenRegister::Vec *Members; 45906f32e7eSjoerg RegSizeInfoByHwMode RSI; 46006f32e7eSjoerg KeyKey46106f32e7eSjoerg Key(const CodeGenRegister::Vec *M, const RegSizeInfoByHwMode &I) 46206f32e7eSjoerg : Members(M), RSI(I) {} 46306f32e7eSjoerg KeyKey46406f32e7eSjoerg Key(const CodeGenRegisterClass &RC) 46506f32e7eSjoerg : Members(&RC.getMembers()), RSI(RC.RSI) {} 46606f32e7eSjoerg 46706f32e7eSjoerg // Lexicographical order of (Members, RegSizeInfoByHwMode). 46806f32e7eSjoerg bool operator<(const Key&) const; 46906f32e7eSjoerg }; 47006f32e7eSjoerg 47106f32e7eSjoerg // Create a non-user defined register class. 47206f32e7eSjoerg CodeGenRegisterClass(CodeGenRegBank&, StringRef Name, Key Props); 47306f32e7eSjoerg 47406f32e7eSjoerg // Called by CodeGenRegBank::CodeGenRegBank(). 47506f32e7eSjoerg static void computeSubClasses(CodeGenRegBank&); 47606f32e7eSjoerg }; 47706f32e7eSjoerg 47806f32e7eSjoerg // Register units are used to model interference and register pressure. 47906f32e7eSjoerg // Every register is assigned one or more register units such that two 48006f32e7eSjoerg // registers overlap if and only if they have a register unit in common. 48106f32e7eSjoerg // 48206f32e7eSjoerg // Normally, one register unit is created per leaf register. Non-leaf 48306f32e7eSjoerg // registers inherit the units of their sub-registers. 48406f32e7eSjoerg struct RegUnit { 48506f32e7eSjoerg // Weight assigned to this RegUnit for estimating register pressure. 48606f32e7eSjoerg // This is useful when equalizing weights in register classes with mixed 48706f32e7eSjoerg // register topologies. 48806f32e7eSjoerg unsigned Weight; 48906f32e7eSjoerg 49006f32e7eSjoerg // Each native RegUnit corresponds to one or two root registers. The full 49106f32e7eSjoerg // set of registers containing this unit can be computed as the union of 49206f32e7eSjoerg // these two registers and their super-registers. 49306f32e7eSjoerg const CodeGenRegister *Roots[2]; 49406f32e7eSjoerg 49506f32e7eSjoerg // Index into RegClassUnitSets where we can find the list of UnitSets that 49606f32e7eSjoerg // contain this unit. 49706f32e7eSjoerg unsigned RegClassUnitSetsIdx; 49806f32e7eSjoerg // A register unit is artificial if at least one of its roots is 49906f32e7eSjoerg // artificial. 50006f32e7eSjoerg bool Artificial; 50106f32e7eSjoerg RegUnitRegUnit50206f32e7eSjoerg RegUnit() : Weight(0), RegClassUnitSetsIdx(0), Artificial(false) { 50306f32e7eSjoerg Roots[0] = Roots[1] = nullptr; 50406f32e7eSjoerg } 50506f32e7eSjoerg getRootsRegUnit50606f32e7eSjoerg ArrayRef<const CodeGenRegister*> getRoots() const { 50706f32e7eSjoerg assert(!(Roots[1] && !Roots[0]) && "Invalid roots array"); 50806f32e7eSjoerg return makeArrayRef(Roots, !!Roots[0] + !!Roots[1]); 50906f32e7eSjoerg } 51006f32e7eSjoerg }; 51106f32e7eSjoerg 51206f32e7eSjoerg // Each RegUnitSet is a sorted vector with a name. 51306f32e7eSjoerg struct RegUnitSet { 51406f32e7eSjoerg typedef std::vector<unsigned>::const_iterator iterator; 51506f32e7eSjoerg 51606f32e7eSjoerg std::string Name; 51706f32e7eSjoerg std::vector<unsigned> Units; 51806f32e7eSjoerg unsigned Weight = 0; // Cache the sum of all unit weights. 51906f32e7eSjoerg unsigned Order = 0; // Cache the sort key. 52006f32e7eSjoerg 52106f32e7eSjoerg RegUnitSet() = default; 52206f32e7eSjoerg }; 52306f32e7eSjoerg 52406f32e7eSjoerg // Base vector for identifying TopoSigs. The contents uniquely identify a 52506f32e7eSjoerg // TopoSig, only computeSuperRegs needs to know how. 52606f32e7eSjoerg typedef SmallVector<unsigned, 16> TopoSigId; 52706f32e7eSjoerg 52806f32e7eSjoerg // CodeGenRegBank - Represent a target's registers and the relations between 52906f32e7eSjoerg // them. 53006f32e7eSjoerg class CodeGenRegBank { 53106f32e7eSjoerg SetTheory Sets; 53206f32e7eSjoerg 53306f32e7eSjoerg const CodeGenHwModes &CGH; 53406f32e7eSjoerg 53506f32e7eSjoerg std::deque<CodeGenSubRegIndex> SubRegIndices; 53606f32e7eSjoerg DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx; 53706f32e7eSjoerg 53806f32e7eSjoerg CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace); 53906f32e7eSjoerg 54006f32e7eSjoerg typedef std::map<SmallVector<CodeGenSubRegIndex*, 8>, 54106f32e7eSjoerg CodeGenSubRegIndex*> ConcatIdxMap; 54206f32e7eSjoerg ConcatIdxMap ConcatIdx; 54306f32e7eSjoerg 54406f32e7eSjoerg // Registers. 54506f32e7eSjoerg std::deque<CodeGenRegister> Registers; 54606f32e7eSjoerg StringMap<CodeGenRegister*> RegistersByName; 54706f32e7eSjoerg DenseMap<Record*, CodeGenRegister*> Def2Reg; 54806f32e7eSjoerg unsigned NumNativeRegUnits; 54906f32e7eSjoerg 55006f32e7eSjoerg std::map<TopoSigId, unsigned> TopoSigs; 55106f32e7eSjoerg 55206f32e7eSjoerg // Includes native (0..NumNativeRegUnits-1) and adopted register units. 55306f32e7eSjoerg SmallVector<RegUnit, 8> RegUnits; 55406f32e7eSjoerg 55506f32e7eSjoerg // Register classes. 55606f32e7eSjoerg std::list<CodeGenRegisterClass> RegClasses; 55706f32e7eSjoerg DenseMap<Record*, CodeGenRegisterClass*> Def2RC; 55806f32e7eSjoerg typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap; 55906f32e7eSjoerg RCKeyMap Key2RC; 56006f32e7eSjoerg 56106f32e7eSjoerg // Remember each unique set of register units. Initially, this contains a 56206f32e7eSjoerg // unique set for each register class. Simliar sets are coalesced with 56306f32e7eSjoerg // pruneUnitSets and new supersets are inferred during computeRegUnitSets. 56406f32e7eSjoerg std::vector<RegUnitSet> RegUnitSets; 56506f32e7eSjoerg 56606f32e7eSjoerg // Map RegisterClass index to the index of the RegUnitSet that contains the 56706f32e7eSjoerg // class's units and any inferred RegUnit supersets. 56806f32e7eSjoerg // 56906f32e7eSjoerg // NOTE: This could grow beyond the number of register classes when we map 57006f32e7eSjoerg // register units to lists of unit sets. If the list of unit sets does not 57106f32e7eSjoerg // already exist for a register class, we create a new entry in this vector. 57206f32e7eSjoerg std::vector<std::vector<unsigned>> RegClassUnitSets; 57306f32e7eSjoerg 57406f32e7eSjoerg // Give each register unit set an order based on sorting criteria. 57506f32e7eSjoerg std::vector<unsigned> RegUnitSetOrder; 57606f32e7eSjoerg 57706f32e7eSjoerg // Keep track of synthesized definitions generated in TupleExpander. 57806f32e7eSjoerg std::vector<std::unique_ptr<Record>> SynthDefs; 57906f32e7eSjoerg 58006f32e7eSjoerg // Add RC to *2RC maps. 58106f32e7eSjoerg void addToMaps(CodeGenRegisterClass*); 58206f32e7eSjoerg 58306f32e7eSjoerg // Create a synthetic sub-class if it is missing. 58406f32e7eSjoerg CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC, 58506f32e7eSjoerg const CodeGenRegister::Vec *Membs, 58606f32e7eSjoerg StringRef Name); 58706f32e7eSjoerg 58806f32e7eSjoerg // Infer missing register classes. 58906f32e7eSjoerg void computeInferredRegisterClasses(); 59006f32e7eSjoerg void inferCommonSubClass(CodeGenRegisterClass *RC); 59106f32e7eSjoerg void inferSubClassWithSubReg(CodeGenRegisterClass *RC); 59206f32e7eSjoerg inferMatchingSuperRegClass(CodeGenRegisterClass * RC)59306f32e7eSjoerg void inferMatchingSuperRegClass(CodeGenRegisterClass *RC) { 59406f32e7eSjoerg inferMatchingSuperRegClass(RC, RegClasses.begin()); 59506f32e7eSjoerg } 59606f32e7eSjoerg 59706f32e7eSjoerg void inferMatchingSuperRegClass( 59806f32e7eSjoerg CodeGenRegisterClass *RC, 59906f32e7eSjoerg std::list<CodeGenRegisterClass>::iterator FirstSubRegRC); 60006f32e7eSjoerg 60106f32e7eSjoerg // Iteratively prune unit sets. 60206f32e7eSjoerg void pruneUnitSets(); 60306f32e7eSjoerg 60406f32e7eSjoerg // Compute a weight for each register unit created during getSubRegs. 60506f32e7eSjoerg void computeRegUnitWeights(); 60606f32e7eSjoerg 60706f32e7eSjoerg // Create a RegUnitSet for each RegClass and infer superclasses. 60806f32e7eSjoerg void computeRegUnitSets(); 60906f32e7eSjoerg 61006f32e7eSjoerg // Populate the Composite map from sub-register relationships. 61106f32e7eSjoerg void computeComposites(); 61206f32e7eSjoerg 61306f32e7eSjoerg // Compute a lane mask for each sub-register index. 61406f32e7eSjoerg void computeSubRegLaneMasks(); 61506f32e7eSjoerg 61606f32e7eSjoerg /// Computes a lane mask for each register unit enumerated by a physical 61706f32e7eSjoerg /// register. 61806f32e7eSjoerg void computeRegUnitLaneMasks(); 61906f32e7eSjoerg 62006f32e7eSjoerg public: 62106f32e7eSjoerg CodeGenRegBank(RecordKeeper&, const CodeGenHwModes&); 622*da58b97aSjoerg CodeGenRegBank(CodeGenRegBank&) = delete; 62306f32e7eSjoerg getSets()62406f32e7eSjoerg SetTheory &getSets() { return Sets; } 62506f32e7eSjoerg getHwModes()62606f32e7eSjoerg const CodeGenHwModes &getHwModes() const { return CGH; } 62706f32e7eSjoerg 62806f32e7eSjoerg // Sub-register indices. The first NumNamedIndices are defined by the user 62906f32e7eSjoerg // in the .td files. The rest are synthesized such that all sub-registers 63006f32e7eSjoerg // have a unique name. getSubRegIndices()63106f32e7eSjoerg const std::deque<CodeGenSubRegIndex> &getSubRegIndices() const { 63206f32e7eSjoerg return SubRegIndices; 63306f32e7eSjoerg } 63406f32e7eSjoerg 635*da58b97aSjoerg // Find a SubRegIndex from its Record def or add to the list if it does 636*da58b97aSjoerg // not exist there yet. 63706f32e7eSjoerg CodeGenSubRegIndex *getSubRegIdx(Record*); 63806f32e7eSjoerg 639*da58b97aSjoerg // Find a SubRegIndex from its Record def. 640*da58b97aSjoerg const CodeGenSubRegIndex *findSubRegIdx(const Record* Def) const; 641*da58b97aSjoerg 64206f32e7eSjoerg // Find or create a sub-register index representing the A+B composition. 64306f32e7eSjoerg CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A, 64406f32e7eSjoerg CodeGenSubRegIndex *B); 64506f32e7eSjoerg 64606f32e7eSjoerg // Find or create a sub-register index representing the concatenation of 64706f32e7eSjoerg // non-overlapping sibling indices. 64806f32e7eSjoerg CodeGenSubRegIndex * 64906f32e7eSjoerg getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8>&); 65006f32e7eSjoerg getRegisters()651*da58b97aSjoerg const std::deque<CodeGenRegister> &getRegisters() const { 652*da58b97aSjoerg return Registers; 653*da58b97aSjoerg } 65406f32e7eSjoerg getRegistersByName()655*da58b97aSjoerg const StringMap<CodeGenRegister *> &getRegistersByName() const { 65606f32e7eSjoerg return RegistersByName; 65706f32e7eSjoerg } 65806f32e7eSjoerg 65906f32e7eSjoerg // Find a register from its Record def. 66006f32e7eSjoerg CodeGenRegister *getReg(Record*); 66106f32e7eSjoerg 66206f32e7eSjoerg // Get a Register's index into the Registers array. getRegIndex(const CodeGenRegister * Reg)66306f32e7eSjoerg unsigned getRegIndex(const CodeGenRegister *Reg) const { 66406f32e7eSjoerg return Reg->EnumValue - 1; 66506f32e7eSjoerg } 66606f32e7eSjoerg 66706f32e7eSjoerg // Return the number of allocated TopoSigs. The first TopoSig representing 66806f32e7eSjoerg // leaf registers is allocated number 0. getNumTopoSigs()66906f32e7eSjoerg unsigned getNumTopoSigs() const { 67006f32e7eSjoerg return TopoSigs.size(); 67106f32e7eSjoerg } 67206f32e7eSjoerg 67306f32e7eSjoerg // Find or create a TopoSig for the given TopoSigId. 67406f32e7eSjoerg // This function is only for use by CodeGenRegister::computeSuperRegs(). 67506f32e7eSjoerg // Others should simply use Reg->getTopoSig(). getTopoSig(const TopoSigId & Id)67606f32e7eSjoerg unsigned getTopoSig(const TopoSigId &Id) { 67706f32e7eSjoerg return TopoSigs.insert(std::make_pair(Id, TopoSigs.size())).first->second; 67806f32e7eSjoerg } 67906f32e7eSjoerg 68006f32e7eSjoerg // Create a native register unit that is associated with one or two root 68106f32e7eSjoerg // registers. 68206f32e7eSjoerg unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = nullptr) { 68306f32e7eSjoerg RegUnits.resize(RegUnits.size() + 1); 68406f32e7eSjoerg RegUnit &RU = RegUnits.back(); 68506f32e7eSjoerg RU.Roots[0] = R0; 68606f32e7eSjoerg RU.Roots[1] = R1; 68706f32e7eSjoerg RU.Artificial = R0->Artificial; 68806f32e7eSjoerg if (R1) 68906f32e7eSjoerg RU.Artificial |= R1->Artificial; 69006f32e7eSjoerg return RegUnits.size() - 1; 69106f32e7eSjoerg } 69206f32e7eSjoerg 69306f32e7eSjoerg // Create a new non-native register unit that can be adopted by a register 69406f32e7eSjoerg // to increase its pressure. Note that NumNativeRegUnits is not increased. newRegUnit(unsigned Weight)69506f32e7eSjoerg unsigned newRegUnit(unsigned Weight) { 69606f32e7eSjoerg RegUnits.resize(RegUnits.size() + 1); 69706f32e7eSjoerg RegUnits.back().Weight = Weight; 69806f32e7eSjoerg return RegUnits.size() - 1; 69906f32e7eSjoerg } 70006f32e7eSjoerg 70106f32e7eSjoerg // Native units are the singular unit of a leaf register. Register aliasing 70206f32e7eSjoerg // is completely characterized by native units. Adopted units exist to give 70306f32e7eSjoerg // register additional weight but don't affect aliasing. isNativeUnit(unsigned RUID)704*da58b97aSjoerg bool isNativeUnit(unsigned RUID) const { 70506f32e7eSjoerg return RUID < NumNativeRegUnits; 70606f32e7eSjoerg } 70706f32e7eSjoerg getNumNativeRegUnits()70806f32e7eSjoerg unsigned getNumNativeRegUnits() const { 70906f32e7eSjoerg return NumNativeRegUnits; 71006f32e7eSjoerg } 71106f32e7eSjoerg getRegUnit(unsigned RUID)71206f32e7eSjoerg RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; } getRegUnit(unsigned RUID)71306f32e7eSjoerg const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; } 71406f32e7eSjoerg getRegClasses()71506f32e7eSjoerg std::list<CodeGenRegisterClass> &getRegClasses() { return RegClasses; } 71606f32e7eSjoerg getRegClasses()71706f32e7eSjoerg const std::list<CodeGenRegisterClass> &getRegClasses() const { 71806f32e7eSjoerg return RegClasses; 71906f32e7eSjoerg } 72006f32e7eSjoerg 72106f32e7eSjoerg // Find a register class from its def. 722*da58b97aSjoerg CodeGenRegisterClass *getRegClass(const Record *) const; 72306f32e7eSjoerg 72406f32e7eSjoerg /// getRegisterClassForRegister - Find the register class that contains the 72506f32e7eSjoerg /// specified physical register. If the register is not in a register 72606f32e7eSjoerg /// class, return null. If the register is in multiple classes, and the 72706f32e7eSjoerg /// classes have a superset-subset relationship and the same set of types, 72806f32e7eSjoerg /// return the superclass. Otherwise return null. 72906f32e7eSjoerg const CodeGenRegisterClass* getRegClassForRegister(Record *R); 73006f32e7eSjoerg 73106f32e7eSjoerg // Analog of TargetRegisterInfo::getMinimalPhysRegClass. Unlike 73206f32e7eSjoerg // getRegClassForRegister, this tries to find the smallest class containing 73306f32e7eSjoerg // the physical register. If \p VT is specified, it will only find classes 73406f32e7eSjoerg // with a matching type 73506f32e7eSjoerg const CodeGenRegisterClass * 73606f32e7eSjoerg getMinimalPhysRegClass(Record *RegRecord, ValueTypeByHwMode *VT = nullptr); 73706f32e7eSjoerg 73806f32e7eSjoerg // Get the sum of unit weights. getRegUnitSetWeight(const std::vector<unsigned> & Units)73906f32e7eSjoerg unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const { 74006f32e7eSjoerg unsigned Weight = 0; 741*da58b97aSjoerg for (unsigned Unit : Units) 742*da58b97aSjoerg Weight += getRegUnit(Unit).Weight; 74306f32e7eSjoerg return Weight; 74406f32e7eSjoerg } 74506f32e7eSjoerg getRegSetIDAt(unsigned Order)74606f32e7eSjoerg unsigned getRegSetIDAt(unsigned Order) const { 74706f32e7eSjoerg return RegUnitSetOrder[Order]; 74806f32e7eSjoerg } 74906f32e7eSjoerg getRegSetAt(unsigned Order)75006f32e7eSjoerg const RegUnitSet &getRegSetAt(unsigned Order) const { 75106f32e7eSjoerg return RegUnitSets[RegUnitSetOrder[Order]]; 75206f32e7eSjoerg } 75306f32e7eSjoerg 75406f32e7eSjoerg // Increase a RegUnitWeight. increaseRegUnitWeight(unsigned RUID,unsigned Inc)75506f32e7eSjoerg void increaseRegUnitWeight(unsigned RUID, unsigned Inc) { 75606f32e7eSjoerg getRegUnit(RUID).Weight += Inc; 75706f32e7eSjoerg } 75806f32e7eSjoerg 75906f32e7eSjoerg // Get the number of register pressure dimensions. getNumRegPressureSets()76006f32e7eSjoerg unsigned getNumRegPressureSets() const { return RegUnitSets.size(); } 76106f32e7eSjoerg 76206f32e7eSjoerg // Get a set of register unit IDs for a given dimension of pressure. getRegPressureSet(unsigned Idx)76306f32e7eSjoerg const RegUnitSet &getRegPressureSet(unsigned Idx) const { 76406f32e7eSjoerg return RegUnitSets[Idx]; 76506f32e7eSjoerg } 76606f32e7eSjoerg 76706f32e7eSjoerg // The number of pressure set lists may be larget than the number of 76806f32e7eSjoerg // register classes if some register units appeared in a list of sets that 76906f32e7eSjoerg // did not correspond to an existing register class. getNumRegClassPressureSetLists()77006f32e7eSjoerg unsigned getNumRegClassPressureSetLists() const { 77106f32e7eSjoerg return RegClassUnitSets.size(); 77206f32e7eSjoerg } 77306f32e7eSjoerg 77406f32e7eSjoerg // Get a list of pressure set IDs for a register class. Liveness of a 77506f32e7eSjoerg // register in this class impacts each pressure set in this list by the 77606f32e7eSjoerg // weight of the register. An exact solution requires all registers in a 77706f32e7eSjoerg // class to have the same class, but it is not strictly guaranteed. getRCPressureSetIDs(unsigned RCIdx)77806f32e7eSjoerg ArrayRef<unsigned> getRCPressureSetIDs(unsigned RCIdx) const { 77906f32e7eSjoerg return RegClassUnitSets[RCIdx]; 78006f32e7eSjoerg } 78106f32e7eSjoerg 78206f32e7eSjoerg // Computed derived records such as missing sub-register indices. 78306f32e7eSjoerg void computeDerivedInfo(); 78406f32e7eSjoerg 78506f32e7eSjoerg // Compute the set of registers completely covered by the registers in Regs. 78606f32e7eSjoerg // The returned BitVector will have a bit set for each register in Regs, 78706f32e7eSjoerg // all sub-registers, and all super-registers that are covered by the 78806f32e7eSjoerg // registers in Regs. 78906f32e7eSjoerg // 79006f32e7eSjoerg // This is used to compute the mask of call-preserved registers from a list 79106f32e7eSjoerg // of callee-saves. 79206f32e7eSjoerg BitVector computeCoveredRegisters(ArrayRef<Record*> Regs); 79306f32e7eSjoerg 79406f32e7eSjoerg // Bit mask of lanes that cover their registers. A sub-register index whose 79506f32e7eSjoerg // LaneMask is contained in CoveringLanes will be completely covered by 79606f32e7eSjoerg // another sub-register with the same or larger lane mask. 79706f32e7eSjoerg LaneBitmask CoveringLanes; 79806f32e7eSjoerg 79906f32e7eSjoerg // Helper function for printing debug information. Handles artificial 80006f32e7eSjoerg // (non-native) reg units. 80106f32e7eSjoerg void printRegUnitName(unsigned Unit) const; 80206f32e7eSjoerg }; 80306f32e7eSjoerg 80406f32e7eSjoerg } // end namespace llvm 80506f32e7eSjoerg 80606f32e7eSjoerg #endif // LLVM_UTILS_TABLEGEN_CODEGENREGISTERS_H 807