diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h index 2edc2985f0ee6..b9e5598738390 100644 --- a/llvm/include/llvm/CodeGen/LiveStacks.h +++ b/llvm/include/llvm/CodeGen/LiveStacks.h @@ -34,6 +34,7 @@ class TargetRegisterInfo; class LiveStacks : public MachineFunctionPass { const TargetRegisterInfo *TRI = nullptr; + const MachineRegisterInfo *MRI = nullptr; /// Special pool allocator for VNInfo's (LiveInterval val#). /// diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index fcdd73d8b65fd..c7067d90a3ce0 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -1586,7 +1586,7 @@ class MachineInstr const TargetRegisterClass *getRegClassConstraintEffectForVReg( Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, - bool ExploreBundle = false) const; + const MachineRegisterInfo &MRI, bool ExploreBundle = false) const; /// Applies the constraints (def/use) implied by the \p OpIdx operand /// to the given \p CurRC. @@ -1600,7 +1600,8 @@ class MachineInstr const TargetRegisterClass * getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, - const TargetRegisterInfo *TRI) const; + const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI) const; /// Add a tie between the register operands at DefIdx and UseIdx. /// The tie will cause the register allocator to ensure that the two @@ -2005,7 +2006,8 @@ class MachineInstr /// If the related operand does not constrained Reg, this returns CurRC. const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl( unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC, - const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; + const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI) const; /// Stores extra instruction information inline or allocates as ExtraInfo /// based on the number of pointers. diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h index 09d9a0b4ec402..71a3baef70e8c 100644 --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -94,6 +94,10 @@ class MachineRegisterInfo { /// all registers that were disabled are removed from the list. SmallVector UpdatedCSRs; + /// The Synthetic field of regclasses. Targets can alter this vector + /// to enable classes dynamically during codegen. + BitVector RegClassSyntheticInfo; + /// RegAllocHints - This vector records register allocation hints for /// virtual registers. For each virtual register, it keeps a pair of hint /// type and hints vector making up the allocation hints. Only the first @@ -257,6 +261,18 @@ class MachineRegisterInfo { /// Notice that it will override ant previously disabled/saved CSRs. void setCalleeSavedRegs(ArrayRef CSRs); + /// Initialize the RegClassSyntheticInfo. It sets the bit position as + /// exactly as the tablegened Synthetic field. Targets can later flip this + /// field to enable/disable the regclass whenever required. + void initializeRegClassSyntheticInfo(); + + /// Change the synthetic info for the regclass \p RC from \p Value. + void changeSyntheticInfoForRC(const TargetRegisterClass *RC, bool Value); + + /// This function checks if \p RC is enabled or not so that it can be included + /// in various regclass related queries. + bool isEnabled(const TargetRegisterClass *RC) const; + // Strictly for use by MachineInstr.cpp. void addRegOperandToUseList(MachineOperand *MO); diff --git a/llvm/include/llvm/CodeGen/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/RegisterBankInfo.h index 62c4a57a605d6..117f381512a1c 100644 --- a/llvm/include/llvm/CodeGen/RegisterBankInfo.h +++ b/llvm/include/llvm/CodeGen/RegisterBankInfo.h @@ -445,7 +445,8 @@ class RegisterBankInfo { /// Get the MinimalPhysRegClass for Reg. /// \pre Reg is a physical register. const TargetRegisterClass * - getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const; + getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI) const; /// Try to get the mapping of \p MI. /// See getInstrMapping for more details on what a mapping represents. diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 59fad88f91b1d..5ef963cae5528 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4384,6 +4384,7 @@ class TargetLowering : public TargetLoweringBase { /// Returns 'true' is the edge is necessary, 'false' otherwise virtual bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, unsigned &PhysReg, int &Cost) const { return false; diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index 117d3f7182974..a3d68d6743ede 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -121,6 +121,9 @@ class TargetRegisterClass { /// Return true if this register class has a defined BaseClassOrder. bool isBaseClass() const { return MC->isBaseClass(); } + /// Return true if this register class is marked synthetic. + bool isSynthetic() const { return MC->isSynthetic(); } + /// Return true if the specified TargetRegisterClass /// is a proper sub-class of this TargetRegisterClass. bool hasSubClass(const TargetRegisterClass *RC) const { @@ -338,20 +341,23 @@ class TargetRegisterInfo : public MCRegisterInfo { /// Returns the Register Class of a physical register of the given type, /// picking the most sub register class of the right type that contains this /// physreg. - const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg, - MVT VT = MVT::Other) const; + const TargetRegisterClass * + getMinimalPhysRegClass(MCRegister Reg, const MachineRegisterInfo &MRI, + MVT VT = MVT::Other) const; /// Returns the Register Class of a physical register of the given type, /// picking the most sub register class of the right type that contains this /// physreg. If there is no register class compatible with the given type, /// returns nullptr. - const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg, - LLT Ty = LLT()) const; + const TargetRegisterClass * + getMinimalPhysRegClassLLT(MCRegister Reg, const MachineRegisterInfo &MRI, + LLT Ty = LLT()) const; /// Return the maximal subclass of the given register class that is /// allocatable or NULL. const TargetRegisterClass * - getAllocatableClass(const TargetRegisterClass *RC) const; + getAllocatableClass(const TargetRegisterClass *RC, + const MachineRegisterInfo &MRI) const; /// Returns a bitset indexed by register number indicating if a register is /// allocatable or not. If a register class is specified, returns the subset @@ -630,7 +636,8 @@ class TargetRegisterInfo : public MCRegisterInfo { /// TableGen will synthesize missing A sub-classes. virtual const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, - const TargetRegisterClass *B, unsigned Idx) const; + const TargetRegisterClass *B, unsigned Idx, + const MachineRegisterInfo &MRI) const; // For a copy-like instruction that defines a register of class DefRC with // subreg index DefSubReg, reading from another source with class SrcRC and @@ -639,7 +646,8 @@ class TargetRegisterInfo : public MCRegisterInfo { virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const; + unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const; /// Returns the largest legal sub-class of RC that /// supports the sub-register index Idx. @@ -769,10 +777,11 @@ class TargetRegisterInfo : public MCRegisterInfo { /// corresponding argument register class. /// /// The function returns NULL if no register class can be found. - const TargetRegisterClass* + const TargetRegisterClass * getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, const TargetRegisterClass *RCB, unsigned SubB, - unsigned &PreA, unsigned &PreB) const; + unsigned &PreA, unsigned &PreB, + const MachineRegisterInfo &MRI) const; //===--------------------------------------------------------------------===// // Register Class Information @@ -809,8 +818,8 @@ class TargetRegisterInfo : public MCRegisterInfo { /// Find the largest common subclass of A and B. /// Return NULL if there is no common subclass. const TargetRegisterClass * - getCommonSubClass(const TargetRegisterClass *A, - const TargetRegisterClass *B) const; + getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B, + const MachineRegisterInfo &MRI) const; /// Returns a TargetRegisterClass used for pointer values. /// If a target supports multiple different pointer register classes, diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h index fb4d11ec1d4d1..1a2ff58c31f5a 100644 --- a/llvm/include/llvm/MC/MCRegisterInfo.h +++ b/llvm/include/llvm/MC/MCRegisterInfo.h @@ -47,6 +47,7 @@ class MCRegisterClass { const int8_t CopyCost; const bool Allocatable; const bool BaseClass; + const bool Synthetic; /// getID() - Return the register class ID number. /// @@ -101,6 +102,9 @@ class MCRegisterClass { /// Return true if this register class has a defined BaseClassOrder. bool isBaseClass() const { return BaseClass; } + /// isSynthetic - Return true if this is a synthetic class. This field helps + /// targets to dynamically enable the regclass during codegen. + bool isSynthetic() const { return Synthetic; } }; /// MCRegisterDesc - This record contains information about a particular diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index cb1c0ed2513d4..0cf9159030bc5 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -338,6 +338,12 @@ class RegisterClass regTypes, int alignment, // Target-specific flags. This becomes the TSFlags field in TargetRegisterClass. bits<8> TSFlags = 0; + // If set to true, the register class won't take part in various regclass queries + // by default. This allows targets to dynamically enable classes for a period + // during codegen so that they can be turned allocatable, copyable, spillable, + // and/or make them available for various regclass queries. + bit Synthetic = false; + // If set then consider this register class to be the base class for registers in // its MemberList. The base class for registers present in multiple base register // classes will be resolved in the order defined by this value, with lower values diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp index ed6ce6bc73d38..93860aae8acfd 100644 --- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp +++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -604,7 +604,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( // check every use of the register and find the largest register class // that can be used in all of them. const TargetRegisterClass *SuperRC = - TRI->getMinimalPhysRegClass(SuperReg, MVT::Other); + TRI->getMinimalPhysRegClass(SuperReg, MRI, MVT::Other); ArrayRef Order = RegClassInfo.getOrder(SuperRC); if (Order.empty()) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 14f2a363f9be6..7b403fee7ed12 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -813,7 +813,7 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes( auto AddEntry = [&](const DbgValueLocEntry &Entry, DIExpressionCursor &Cursor) { if (Entry.isLocation()) { - if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, + if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor, Entry.getLoc().getReg())) return false; } else if (Entry.isInt()) { @@ -910,7 +910,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI, addOpAddress(*Loc, FrameSymbol); else DwarfExpr.addMachineRegExpression( - *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); + *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(), + Cursor, FrameReg); DwarfExpr.addExpression(std::move(Cursor)); } if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { @@ -940,7 +941,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes( DIExpressionCursor Cursor(Expr.getElements()); DwarfExpr.beginEntryValueExpression(Cursor); DwarfExpr.addMachineRegExpression( - *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register); + *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(), + Cursor, Register); DwarfExpr.addExpression(std::move(Cursor)); } addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); @@ -1557,7 +1559,8 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, DIExpressionCursor Cursor({}); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) + if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor, + Location.getReg())) return; DwarfExpr.addExpression(std::move(Cursor)); @@ -1587,7 +1590,8 @@ void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die, DwarfExpr.beginEntryValueExpression(Cursor); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) + if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor, + Location.getReg())) return; DwarfExpr.addExpression(std::move(Cursor)); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6b5ad62e083e3..0b372d7b0e1bf 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2652,7 +2652,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, DwarfExpr.beginEntryValueExpression(ExprCursor); const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg())) + if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), ExprCursor, + Location.getReg())) return; return DwarfExpr.addExpression(std::move(ExprCursor)); } @@ -2673,7 +2674,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, DwarfExpr.setMemoryLocationKind(); const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) + if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), Cursor, + Location.getReg())) return false; } else if (Entry.isTargetIndexLocation()) { TargetIndexLocation Loc = Entry.getTargetIndexLocation(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index a74d43897d45b..6d4794d27effb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -97,6 +97,7 @@ void DwarfExpression::addAnd(unsigned Mask) { } bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI, llvm::Register MachineReg, unsigned MaxSize) { if (!MachineReg.isPhysical()) { @@ -134,7 +135,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, // For example, Q0 on ARM is a composition of D0+D1. unsigned CurPos = 0; // The size of the register in bits. - const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg); + const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg, MRI); unsigned RegSize = TRI.getRegSizeInBits(*RC); // Keep track of the bits in the register we already emitted, so we // can avoid emitting redundant aliasing subregs. Because this is @@ -248,11 +249,13 @@ void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) { } bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI, DIExpressionCursor &ExprCursor, llvm::Register MachineReg, unsigned FragmentOffsetInBits) { auto Fragment = ExprCursor.getFragmentInfo(); - if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) { + if (!addMachineReg(TRI, MRI, MachineReg, + Fragment ? Fragment->SizeInBits : ~1U)) { LocationKind = Unknown; return false; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 667a9efc6f6c0..70ab73b5996b4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -245,7 +245,8 @@ class DwarfExpression { /// multiple subregisters that alias the register. /// /// \return false if no DWARF register exists for MachineReg. - bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg, + bool addMachineReg(const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI, llvm::Register MachineReg, unsigned MaxSize = ~1U); /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment. @@ -325,6 +326,7 @@ class DwarfExpression { /// \return false if no DWARF register exists /// for MachineReg. bool addMachineRegExpression(const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits = 0); diff --git a/llvm/lib/CodeGen/DetectDeadLanes.cpp b/llvm/lib/CodeGen/DetectDeadLanes.cpp index 86e9f3abe010d..57c5466129162 100644 --- a/llvm/lib/CodeGen/DetectDeadLanes.cpp +++ b/llvm/lib/CodeGen/DetectDeadLanes.cpp @@ -97,12 +97,12 @@ static bool isCrossCopy(const MachineRegisterInfo &MRI, unsigned PreA, PreB; // Unused. if (SrcSubIdx && DstSubIdx) return !TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA, - PreB); + PreB, MRI); if (SrcSubIdx) - return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx); + return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx, MRI); if (DstSubIdx) - return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx); - return !TRI.getCommonSubClass(SrcRC, DstRC); + return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx, MRI); + return !TRI.getCommonSubClass(SrcRC, DstRC, MRI); } void DeadLaneDetector::addUsedLanesOnOperand(const MachineOperand &MO, diff --git a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp index 4d668c53f7156..6732a814f5440 100644 --- a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp +++ b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp @@ -89,8 +89,9 @@ INITIALIZE_PASS_END(FixupStatepointCallerSaved, DEBUG_TYPE, "Fixup Statepoint Caller Saved", false, false) // Utility function to get size of the register. -static unsigned getRegisterSize(const TargetRegisterInfo &TRI, Register Reg) { - const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg); +static unsigned getRegisterSize(const TargetRegisterInfo &TRI, Register Reg, + const MachineRegisterInfo &MRI) { + const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg, MRI); return TRI.getSpillSize(*RC); } @@ -124,6 +125,7 @@ static Register performCopyPropagation(Register Reg, MachineBasicBlock *MBB = RI->getParent(); MachineBasicBlock::reverse_iterator E = MBB->rend(); MachineInstr *Def = nullptr, *Use = nullptr; + const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); for (auto It = ++(RI.getReverse()); It != E; ++It) { if (It->readsRegister(Reg, &TRI) && !Use) Use = &*It; @@ -142,7 +144,7 @@ static Register performCopyPropagation(Register Reg, Register SrcReg = DestSrc->Source->getReg(); - if (getRegisterSize(TRI, Reg) != getRegisterSize(TRI, SrcReg)) + if (getRegisterSize(TRI, Reg, MRI) != getRegisterSize(TRI, SrcReg, MRI)) return Reg; LLVM_DEBUG(dbgs() << "spillRegisters: perform copy propagation " @@ -209,6 +211,7 @@ class FrameIndexesCache { }; MachineFrameInfo &MFI; const TargetRegisterInfo &TRI; + const MachineRegisterInfo &MRI; // Map size to list of frame indexes of this size. If the mode is // FixupSCSExtendSlotSize then the key 0 is used to keep all frame indexes. // If the size of required spill slot is greater than in a cache then the @@ -232,8 +235,9 @@ class FrameIndexesCache { } public: - FrameIndexesCache(MachineFrameInfo &MFI, const TargetRegisterInfo &TRI) - : MFI(MFI), TRI(TRI) {} + FrameIndexesCache(MachineFrameInfo &MFI, const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI) + : MFI(MFI), TRI(TRI), MRI(MRI) {} // Reset the current state of used frame indexes. After invocation of // this function all frame indexes are available for allocation with // the exception of slots reserved for landing pad processing (if any). @@ -265,7 +269,7 @@ class FrameIndexesCache { } } - unsigned Size = getRegisterSize(TRI, Reg); + unsigned Size = getRegisterSize(TRI, Reg, MRI); FrameIndexesPerSize &Line = getCacheBucket(Size); while (Line.Index < Line.Slots.size()) { int FI = Line.Slots[Line.Index++]; @@ -299,11 +303,12 @@ class FrameIndexesCache { // Sort all registers to spill in descendent order. In the // FixupSCSExtendSlotSize mode it will minimize the total frame size. // In non FixupSCSExtendSlotSize mode we can skip this step. - void sortRegisters(SmallVectorImpl &Regs) { + void sortRegisters(SmallVectorImpl &Regs, + const MachineRegisterInfo &MRI) { if (!FixupSCSExtendSlotSize) return; llvm::sort(Regs, [&](Register &A, Register &B) { - return getRegisterSize(TRI, A) > getRegisterSize(TRI, B); + return getRegisterSize(TRI, A, MRI) > getRegisterSize(TRI, B, MRI); }); } }; @@ -398,7 +403,7 @@ class StatepointState { RegsToSpill.push_back(Reg); OpsToSpill.push_back(Idx); } - CacheFI.sortRegisters(RegsToSpill); + CacheFI.sortRegisters(RegsToSpill, MF.getRegInfo()); return !RegsToSpill.empty(); } @@ -418,7 +423,8 @@ class StatepointState { bool IsKill = true; MachineBasicBlock::iterator InsertBefore(MI); Reg = performCopyPropagation(Reg, InsertBefore, IsKill, TII, TRI); - const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + TRI.getMinimalPhysRegClass(Reg, MF.getRegInfo()); LLVM_DEBUG(dbgs() << "Insert spill before " << *InsertBefore); TII.storeRegToStackSlot(*MI.getParent(), InsertBefore, Reg, IsKill, FI, @@ -428,7 +434,8 @@ class StatepointState { void insertReloadBefore(unsigned Reg, MachineBasicBlock::iterator It, MachineBasicBlock *MBB) { - const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + TRI.getMinimalPhysRegClass(Reg, MF.getRegInfo()); int FI = RegToSlotIdx[Reg]; if (It != MBB->end()) { TII.loadRegFromStackSlot(*MBB, It, Reg, FI, RC, &TRI, Register()); @@ -519,7 +526,7 @@ class StatepointState { if (I == OpsToSpill[CurOpIdx]) { int FI = RegToSlotIdx[MO.getReg()]; MIB.addImm(StackMaps::IndirectMemRefOp); - MIB.addImm(getRegisterSize(TRI, MO.getReg())); + MIB.addImm(getRegisterSize(TRI, MO.getReg(), MF.getRegInfo())); assert(MO.isReg() && "Should be register"); assert(MO.getReg().isPhysical() && "Should be physical register"); MIB.addFrameIndex(FI); @@ -538,6 +545,7 @@ class StatepointState { assert(CurOpIdx == (OpsToSpill.size() - 1) && "Not all operands processed"); // Add mem operands. NewMI->setMemRefs(MF, MI.memoperands()); + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (auto It : RegToSlotIdx) { Register R = It.first; int FrameIndex = It.second; @@ -546,7 +554,7 @@ class StatepointState { if (is_contained(RegsToReload, R)) Flags |= MachineMemOperand::MOStore; auto *MMO = - MF.getMachineMemOperand(PtrInfo, Flags, getRegisterSize(TRI, R), + MF.getMachineMemOperand(PtrInfo, Flags, getRegisterSize(TRI, R, MRI), MFI.getObjectAlign(FrameIndex)); NewMI->addMemOperand(MF, MMO); } @@ -570,7 +578,7 @@ class StatepointProcessor { public: StatepointProcessor(MachineFunction &MF) : MF(MF), TRI(*MF.getSubtarget().getRegisterInfo()), - CacheFI(MF.getFrameInfo(), TRI) {} + CacheFI(MF.getFrameInfo(), TRI, MF.getRegInfo()) {} bool process(MachineInstr &MI, bool AllowGCPtrInCSR) { StatepointOpers SO(&MI); diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp index a9fa73b60a097..8d597ceb0a043 100644 --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -124,10 +124,10 @@ Register llvm::constrainOperandRegClass( // register types (E.g., AMDGPU's VGPR and AGPR). The regbank ambiguity // resolved by targets during regbankselect should not be overridden. if (const auto *SubRC = TRI.getCommonSubClass( - OpRC, TRI.getConstrainedRegClassForOperand(RegMO, MRI))) + OpRC, TRI.getConstrainedRegClassForOperand(RegMO, MRI), MRI)) OpRC = SubRC; - OpRC = TRI.getAllocatableClass(OpRC); + OpRC = TRI.getAllocatableClass(OpRC, MRI); } if (!OpRC) { diff --git a/llvm/lib/CodeGen/LiveStacks.cpp b/llvm/lib/CodeGen/LiveStacks.cpp index 8fc5a929d77b2..4290d511dd1c2 100644 --- a/llvm/lib/CodeGen/LiveStacks.cpp +++ b/llvm/lib/CodeGen/LiveStacks.cpp @@ -45,6 +45,7 @@ void LiveStacks::releaseMemory() { bool LiveStacks::runOnMachineFunction(MachineFunction &MF) { TRI = MF.getSubtarget().getRegisterInfo(); + MRI = &MF.getRegInfo(); // FIXME: No analysis is being done right now. We are relying on the // register allocators to provide the information. return false; @@ -64,7 +65,7 @@ LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { } else { // Use the largest common subclass register class. const TargetRegisterClass *OldRC = S2RCMap[Slot]; - S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC); + S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC, *MRI); } return I->second; } diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp index e09318a486955..27e72ccc74052 100644 --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -687,7 +687,7 @@ bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS, Error = true; break; case VRegInfo::NORMAL: - if (!Info.D.RC->isAllocatable()) { + if (!Info.D.RC->isAllocatable() || Info.D.RC->isSynthetic()) { error(Twine("Cannot use non-allocatable class '") + TRI->getRegClassName(Info.D.RC) + "' for virtual register " + Name + " in function '" + MF.getName() + "'"); diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp index 26a8d00e66265..44ade0d87159a 100644 --- a/llvm/lib/CodeGen/MachineCSE.cpp +++ b/llvm/lib/CodeGen/MachineCSE.cpp @@ -196,7 +196,7 @@ bool MachineCSE::PerformTrivialCopyPropagation(MachineInstr *MI, // cse-add-with-overflow.ll). This can be done here as follows: // if (SrcSubReg) // RC = TRI->getMatchingSuperRegClass(MRI->getRegClass(SrcReg), RC, - // SrcSubReg); + // SrcSubReg, MRI); // MO.substVirtReg(SrcReg, SrcSubReg, *TRI); // // The 2-addr pass has been updated to handle coalesced subregs. However, diff --git a/llvm/lib/CodeGen/MachineCombiner.cpp b/llvm/lib/CodeGen/MachineCombiner.cpp index a4c87a7678bd8..703af75ac5c18 100644 --- a/llvm/lib/CodeGen/MachineCombiner.cpp +++ b/llvm/lib/CodeGen/MachineCombiner.cpp @@ -175,7 +175,7 @@ bool MachineCombiner::isTransientMI(const MachineInstr *MI) { auto SrcSub = MI->getOperand(1).getSubReg(); auto SrcRC = MRI->getRegClass(Src); auto DstRC = MRI->getRegClass(Dst); - return TRI->getMatchingSuperRegClass(SrcRC, DstRC, SrcSub) != nullptr; + return TRI->getMatchingSuperRegClass(SrcRC, DstRC, SrcSub, *MRI) != nullptr; } if (Src.isPhysical() && Dst.isPhysical()) diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index fe2f9ccd33a33..79f3873c85852 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -940,36 +940,40 @@ MachineInstr::getRegClassConstraint(unsigned OpIdx, const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, - const TargetRegisterInfo *TRI, bool ExploreBundle) const { + const TargetRegisterInfo *TRI, const MachineRegisterInfo &MRI, + bool ExploreBundle) const { // Check every operands inside the bundle if we have // been asked to. if (ExploreBundle) for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; ++OpndIt) CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( - OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); + OpndIt.getOperandNo(), Reg, CurRC, TII, TRI, MRI); else // Otherwise, just check the current operands. for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) - CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); + CurRC = + getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI, MRI); return CurRC; } const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC, - const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { + const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI) const { assert(CurRC && "Invalid initial register class"); // Check if Reg is constrained by some of its use/def from MI. const MachineOperand &MO = getOperand(OpIdx); if (!MO.isReg() || MO.getReg() != Reg) return CurRC; // If yes, accumulate the constraints through the operand. - return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); + return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI, MRI); } const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( unsigned OpIdx, const TargetRegisterClass *CurRC, - const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { + const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI) const { const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); const MachineOperand &MO = getOperand(OpIdx); assert(MO.isReg() && @@ -977,11 +981,11 @@ const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( assert(CurRC && "Invalid initial register class"); if (unsigned SubIdx = MO.getSubReg()) { if (OpRC) - CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); + CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx, MRI); else CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); } else if (OpRC) - CurRC = TRI->getCommonSubClass(CurRC, OpRC); + CurRC = TRI->getCommonSubClass(CurRC, OpRC, MRI); return CurRC; } diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp index b0c1838b3ff0e..c979e3d5e9cf4 100644 --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -48,6 +48,7 @@ MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF) RegAllocHints.reserve(256); UsedPhysRegMask.resize(NumRegs); PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]()); + initializeRegClassSyntheticInfo(); TheDelegates.clear(); } @@ -55,7 +56,8 @@ MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF) /// void MachineRegisterInfo::setRegClass(Register Reg, const TargetRegisterClass *RC) { - assert(RC && RC->isAllocatable() && "Invalid RC for virtual register"); + assert(RC && isEnabled(RC) && RC->isAllocatable() && + "Invalid RC for virtual register"); VRegInfo[Reg].first = RC; } @@ -71,7 +73,7 @@ constrainRegClass(MachineRegisterInfo &MRI, Register Reg, if (OldRC == RC) return RC; const TargetRegisterClass *NewRC = - MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC); + MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC, MRI); if (!NewRC || NewRC == OldRC) return NewRC; if (NewRC->getNumRegs() < MinNumRegs) @@ -134,7 +136,7 @@ MachineRegisterInfo::recomputeRegClass(Register Reg) { MachineInstr *MI = MO.getParent(); unsigned OpNo = &MO - &MI->getOperand(0); NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII, - getTargetRegisterInfo()); + getTargetRegisterInfo(), *this); if (!NewRC || NewRC == OldRC) return false; } @@ -159,6 +161,8 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass, assert(RegClass && "Cannot create register without RegClass!"); assert(RegClass->isAllocatable() && "Virtual register RegClass must be allocatable."); + assert(isEnabled(RegClass) && + "RegClass must be enabled first to create its virtual registers."); // New virtual register number. Register Reg = createIncompleteVirtualRegister(Name); @@ -650,6 +654,31 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef CSRs) { IsUpdatedCSRsInitialized = true; } +void MachineRegisterInfo::initializeRegClassSyntheticInfo() { + const TargetRegisterInfo *TRI = getTargetRegisterInfo(); + + RegClassSyntheticInfo.resize(TRI->getNumRegClasses()); + for (const TargetRegisterClass *RC : TRI->regclasses()) { + if (RC->isSynthetic()) + RegClassSyntheticInfo.set(RC->getID()); + } +} + +void MachineRegisterInfo::changeSyntheticInfoForRC( + const TargetRegisterClass *RC, bool Value) { + assert(RC->isSynthetic() && "Regclasses can be enabled/disabled dynamically " + "only if marked synthetic."); + + if (Value) + RegClassSyntheticInfo.set(RC->getID()); + else + RegClassSyntheticInfo.reset(RC->getID()); +} + +bool MachineRegisterInfo::isEnabled(const TargetRegisterClass *RC) const { + return !RegClassSyntheticInfo.test(RC->getID()); +} + bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const { const TargetRegisterInfo *TRI = getTargetRegisterInfo(); for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) { diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index c69d36fc7fdd6..a33653160cb69 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -2109,14 +2109,14 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { TypeSize DstSize = TRI->getRegSizeInBits(DstReg, *MRI); if (SrcReg.isPhysical() && DstTy.isValid()) { const TargetRegisterClass *SrcRC = - TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy); + TRI->getMinimalPhysRegClassLLT(SrcReg, *MRI, DstTy); if (SrcRC) SrcSize = TRI->getRegSizeInBits(*SrcRC); } if (DstReg.isPhysical() && SrcTy.isValid()) { const TargetRegisterClass *DstRC = - TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy); + TRI->getMinimalPhysRegClassLLT(DstReg, *MRI, SrcTy); if (DstRC) DstSize = TRI->getRegSizeInBits(*DstRC); } @@ -2490,7 +2490,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { report("No largest legal super class exists.", MO, MONum); return; } - DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx); + DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx, *MRI); if (!DRC) { report("No matching super-reg register class.", MO, MONum); return; diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp index 1b1f22e827cb1..d5809fa46939b 100644 --- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp +++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp @@ -793,7 +793,7 @@ bool PeepholeOptimizer::findNextSource(RegSubRegPair RegSubReg, // Keep following the chain if the value isn't any better yet. const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg); if (!TRI->shouldRewriteCopySrc(DefRC, RegSubReg.SubReg, SrcRC, - CurSrcPair.SubReg)) + CurSrcPair.SubReg, *MRI)) continue; // We currently cannot deal with subreg operands on PHI instructions diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index eaf96ec5cbde8..77271140cb7fa 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -477,7 +477,8 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F, continue; unsigned Reg = CS.getReg(); - const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + RegInfo->getMinimalPhysRegClass(Reg, F.getRegInfo()); int FrameIdx; if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) { @@ -607,7 +608,8 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock, TII.get(TargetOpcode::COPY), CS.getDstReg()) .addReg(Reg, getKillRegState(true)); } else { - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + TRI->getMinimalPhysRegClass(Reg, MF.getRegInfo()); TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC, TRI, Register()); } @@ -634,7 +636,8 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock, BuildMI(RestoreBlock, I, DebugLoc(), TII.get(TargetOpcode::COPY), Reg) .addReg(CI.getDstReg(), getKillRegState(true)); } else { - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + TRI->getMinimalPhysRegClass(Reg, MF.getRegInfo()); TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI, Register()); assert(I != RestoreBlock.begin() && diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index a208bf89fadf2..decf7b6cda14a 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -1342,8 +1342,9 @@ static unsigned getNumAllocatableRegsForConstraints( assert(SuperRC && "Invalid register class"); const TargetRegisterClass *ConstrainedRC = - MI->getRegClassConstraintEffectForVReg(Reg, SuperRC, TII, TRI, - /* ExploreBundle */ true); + MI->getRegClassConstraintEffectForVReg( + Reg, SuperRC, TII, TRI, MI->getParent()->getParent()->getRegInfo(), + /* ExploreBundle */ true); if (!ConstrainedRC) return 0; return RCI.getNumAllocatableRegs(ConstrainedRC); diff --git a/llvm/lib/CodeGen/RegisterBank.cpp b/llvm/lib/CodeGen/RegisterBank.cpp index bdc6df78fd3d9..ac4ef3344e7eb 100644 --- a/llvm/lib/CodeGen/RegisterBank.cpp +++ b/llvm/lib/CodeGen/RegisterBank.cpp @@ -36,7 +36,7 @@ bool RegisterBank::verify(const RegisterBankInfo &RBI, for (unsigned SubRCId = 0; SubRCId != End; ++SubRCId) { const TargetRegisterClass &SubRC = *TRI.getRegClass(RCId); - if (!RC.hasSubClassEq(&SubRC)) + if (SubRC.isSynthetic() || !RC.hasSubClassEq(&SubRC)) continue; // Verify that the Size of the register bank is big enough to cover @@ -91,7 +91,7 @@ void RegisterBank::print(raw_ostream &OS, bool IsForDebug, for (unsigned RCId = 0, End = TRI->getNumRegClasses(); RCId != End; ++RCId) { const TargetRegisterClass &RC = *TRI->getRegClass(RCId); - if (covers(RC)) + if (covers(RC) && !RC.isSynthetic()) OS << LS << TRI->getRegClassName(&RC); } } diff --git a/llvm/lib/CodeGen/RegisterBankInfo.cpp b/llvm/lib/CodeGen/RegisterBankInfo.cpp index 5548430d1b0ae..b57a19dd4ad85 100644 --- a/llvm/lib/CodeGen/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/RegisterBankInfo.cpp @@ -86,7 +86,7 @@ RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI, if (!Reg.isVirtual()) { // FIXME: This was probably a copy to a virtual register that does have a // type we could use. - const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, TRI); + const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, TRI, MRI); return RC ? &getRegBankFromRegClass(*RC, LLT()) : nullptr; } @@ -101,12 +101,14 @@ RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterClass * RegisterBankInfo::getMinimalPhysRegClass(Register Reg, - const TargetRegisterInfo &TRI) const { + const TargetRegisterInfo &TRI, + const MachineRegisterInfo &MRI) const { assert(Reg.isPhysical() && "Reg must be a physreg"); const auto &RegRCIt = PhysRegMinimalRCs.find(Reg); if (RegRCIt != PhysRegMinimalRCs.end()) return RegRCIt->second; - const TargetRegisterClass *PhysRC = TRI.getMinimalPhysRegClassLLT(Reg, LLT()); + const TargetRegisterClass *PhysRC = + TRI.getMinimalPhysRegClassLLT(Reg, MRI, LLT()); PhysRegMinimalRCs[Reg] = PhysRC; return PhysRC; } @@ -503,7 +505,7 @@ TypeSize RegisterBankInfo::getSizeInBits(Register Reg, // Instead, we need to access a register class that contains Reg and // get the size of that register class. // Because this is expensive, we'll cache the register class by calling - auto *RC = getMinimalPhysRegClass(Reg, TRI); + auto *RC = getMinimalPhysRegClass(Reg, TRI, MRI); assert(RC && "Expecting Register class"); return TRI.getRegSizeInBits(*RC); } diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index 7e9c992031f8d..ff300430d38d0 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -498,21 +498,21 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { if (Src == Dst && SrcSub != DstSub) return false; - NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub, - SrcIdx, DstIdx); + NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub, SrcIdx, + DstIdx, MRI); if (!NewRC) return false; } else if (DstSub) { // SrcReg will be merged with a sub-register of DstReg. SrcIdx = DstSub; - NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub); + NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub, MRI); } else if (SrcSub) { // DstReg will be merged with a sub-register of SrcReg. DstIdx = SrcSub; - NewRC = TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSub); + NewRC = TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSub, MRI); } else { // This is a straight copy without sub-registers. - NewRC = TRI.getCommonSubClass(DstRC, SrcRC); + NewRC = TRI.getCommonSubClass(DstRC, SrcRC, MRI); } // The combined constraint may be impossible to satisfy. @@ -1387,7 +1387,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, && "Shouldn't have SrcIdx+DstIdx at this point"); const TargetRegisterClass *DstRC = MRI->getRegClass(DstReg); const TargetRegisterClass *CommonRC = - TRI->getCommonSubClass(DefRC, DstRC); + TRI->getCommonSubClass(DefRC, DstRC, *MRI); if (CommonRC != nullptr) { NewRC = CommonRC; @@ -1481,9 +1481,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP, if (DefRC != nullptr) { if (NewIdx) - NewRC = TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx); + NewRC = TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx, *MRI); else - NewRC = TRI->getCommonSubClass(NewRC, DefRC); + NewRC = TRI->getCommonSubClass(NewRC, DefRC, *MRI); assert(NewRC && "subreg chosen for remat incompatible with instruction"); } // Remap subranges to new lanemask and change register class. diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f199625bf67ad..a8a4286c26230 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -19094,7 +19094,8 @@ struct LoadedSlice { const TargetRegisterInfo *TRI = DAG->getSubtarget().getRegisterInfo(); // Assume bitcasts are cheap, unless both register classes do not // explicitly share a common sub class. - if (!TRI || TRI->getCommonSubClass(ArgRC, ResRC)) + if (!TRI || TRI->getCommonSubClass(ArgRC, ResRC, + DAG->getMachineFunction().getRegInfo())) return false; // Check if it will be merged with the load. diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 54409cbf91f1f..a557406b236fb 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -131,13 +131,13 @@ void InstrEmitter::EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, const TargetRegisterClass *RC = nullptr; if (i + II.getNumDefs() < II.getNumOperands()) { RC = TRI->getAllocatableClass( - TII->getRegClass(II, i + II.getNumDefs(), TRI, *MF)); + TII->getRegClass(II, i + II.getNumDefs(), TRI, *MF), *MRI); } if (!UseRC) UseRC = RC; else if (RC) { const TargetRegisterClass *ComRC = - TRI->getCommonSubClass(UseRC, RC); + TRI->getCommonSubClass(UseRC, RC, *MRI); // If multiple uses expect disjoint register classes, we emit // copies in AddRegisterOperand. if (ComRC) @@ -152,7 +152,7 @@ void InstrEmitter::EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, } const TargetRegisterClass *SrcRC = nullptr, *DstRC = nullptr; - SrcRC = TRI->getMinimalPhysRegClass(SrcReg, VT); + SrcRC = TRI->getMinimalPhysRegClass(SrcReg, *MRI, VT); // Figure out the register class to create for the destreg. if (VRBase) { @@ -203,7 +203,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, // register instead of creating a new vreg. Register VRBase; const TargetRegisterClass *RC = - TRI->getAllocatableClass(TII->getRegClass(II, i, TRI, *MF)); + TRI->getAllocatableClass(TII->getRegClass(II, i, TRI, *MF), *MRI); // Always let the value type influence the used register class. The // constraints on the instruction may be too lax to represent the value // type correctly. For example, a 64-bit float (X86::FR64) can't live in @@ -213,7 +213,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, Node->getSimpleValueType(i), (Node->isDivergent() || (RC && TRI->isDivergentRegClass(RC)))); if (RC) - VTRC = TRI->getCommonSubClass(RC, VTRC); + VTRC = TRI->getCommonSubClass(RC, VTRC, *MRI); if (VTRC) RC = VTRC; } @@ -350,7 +350,7 @@ InstrEmitter::AddRegisterOperand(MachineInstrBuilder &MIB, const TargetRegisterClass *ConstrainedRC = MRI->constrainRegClass(VReg, OpRC, MinNumRegs); if (!ConstrainedRC) { - OpRC = TRI->getAllocatableClass(OpRC); + OpRC = TRI->getAllocatableClass(OpRC, *MRI); assert(OpRC && "Constraints cannot be fulfilled for allocation"); Register NewVReg = MRI->createVirtualRegister(OpRC); BuildMI(*MBB, InsertPos, Op.getNode()->getDebugLoc(), @@ -412,7 +412,8 @@ void InstrEmitter::AddOperand(MachineInstrBuilder &MIB, Register VReg = R->getReg(); MVT OpVT = Op.getSimpleValueType(); const TargetRegisterClass *IIRC = - II ? TRI->getAllocatableClass(TII->getRegClass(*II, IIOpNum, TRI, *MF)) + II ? TRI->getAllocatableClass(TII->getRegClass(*II, IIOpNum, TRI, *MF), + *MRI) : nullptr; const TargetRegisterClass *OpRC = TLI->isTypeLegal(OpVT) @@ -640,7 +641,7 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node, // Create the new VReg in the destination class and emit a copy. unsigned DstRCIdx = Node->getConstantOperandVal(1); const TargetRegisterClass *DstRC = - TRI->getAllocatableClass(TRI->getRegClass(DstRCIdx)); + TRI->getAllocatableClass(TRI->getRegClass(DstRCIdx), *MRI); Register NewVReg = MRI->createVirtualRegister(DstRC); BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TargetOpcode::COPY), NewVReg).addReg(VReg); @@ -658,7 +659,8 @@ void InstrEmitter::EmitRegSequence(SDNode *Node, bool IsClone, bool IsCloned) { unsigned DstRCIdx = Node->getConstantOperandVal(0); const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx); - Register NewVReg = MRI->createVirtualRegister(TRI->getAllocatableClass(RC)); + Register NewVReg = + MRI->createVirtualRegister(TRI->getAllocatableClass(RC, *MRI)); const MCInstrDesc &II = TII->get(TargetOpcode::REG_SEQUENCE); MachineInstrBuilder MIB = BuildMI(*MF, Node->getDebugLoc(), II, NewVReg); unsigned NumOps = Node->getNumOperands(); @@ -681,7 +683,7 @@ void InstrEmitter::EmitRegSequence(SDNode *Node, unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap); const TargetRegisterClass *TRC = MRI->getRegClass(SubReg); const TargetRegisterClass *SRC = - TRI->getMatchingSuperRegClass(RC, TRC, SubIdx); + TRI->getMatchingSuperRegClass(RC, TRC, SubIdx, *MRI); if (SRC && SRC != RC) { MRI->setRegClass(NewVReg, SRC); RC = SRC; diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp index e3acb58327a8c..f6124201775d9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp @@ -581,7 +581,7 @@ void ScheduleDAGFast::ListScheduleBottomUp() { SUnit *LRDef = LiveRegDefs[Reg]; MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); const TargetRegisterClass *RC = - TRI->getMinimalPhysRegClass(Reg, VT); + TRI->getMinimalPhysRegClass(Reg, MRI, VT); const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); // If cross copy register class is the same as RC, then it must be diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index e4ee3fd99f16e..699fab5333e5c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -1561,8 +1561,7 @@ SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() { unsigned Reg = LRegs[0]; SUnit *LRDef = LiveRegDefs[Reg]; MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); - const TargetRegisterClass *RC = - TRI->getMinimalPhysRegClass(Reg, VT); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT); const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); // If cross copy register class is the same as RC, then it must be possible diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index c9e2745f00c95..07728bd3b4354 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -111,12 +111,14 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, const TargetLowering &TLI, + const MachineRegisterInfo &MRI, unsigned &PhysReg, int &Cost) { if (Op != 2 || User->getOpcode() != ISD::CopyToReg) return; unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TLI.checkForPhysRegDependency(Def, User, Op, TRI, TII, PhysReg, Cost)) + if (TLI.checkForPhysRegDependency(Def, User, Op, TRI, MRI, TII, PhysReg, + Cost)) return; if (Register::isVirtualRegister(Reg)) @@ -134,7 +136,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, if (PhysReg != 0) { const TargetRegisterClass *RC = - TRI->getMinimalPhysRegClass(Reg, Def->getSimpleValueType(ResNo)); + TRI->getMinimalPhysRegClass(Reg, MRI, Def->getSimpleValueType(ResNo)); Cost = RC->getCopyCost(); } } @@ -490,7 +492,7 @@ void ScheduleDAGSDNodes::AddSchedEdges() { int Cost = 1; // Determine if this is a physical register dependency. const TargetLowering &TLI = DAG->getTargetLoweringInfo(); - CheckForPhysRegDependency(OpN, N, i, TRI, TII, TLI, PhysReg, Cost); + CheckForPhysRegDependency(OpN, N, i, TRI, TII, TLI, MRI, PhysReg, Cost); assert((PhysReg == 0 || !isChain) && "Chain dependence via physreg data?"); // FIXME: See ScheduleDAGSDNodes::EmitCopyFromReg. For now, scheduler diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 2d63774c75e37..982d1a0c44f77 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -9738,9 +9738,11 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call, Register TiedReg = R->getReg(); MVT RegVT = R->getSimpleValueType(0); const TargetRegisterClass *RC = - TiedReg.isVirtual() ? MRI.getRegClass(TiedReg) - : RegVT != MVT::Untyped ? TLI.getRegClassFor(RegVT) - : TRI.getMinimalPhysRegClass(TiedReg); + TiedReg.isVirtual() + ? MRI.getRegClass(TiedReg) + : RegVT != MVT::Untyped + ? TLI.getRegClassFor(RegVT) + : TRI.getMinimalPhysRegClass(TiedReg, MRI); for (unsigned i = 0, e = Flag.getNumOperandRegisters(); i != e; ++i) Regs.push_back(MRI.createVirtualRegister(RC)); diff --git a/llvm/lib/CodeGen/StackMaps.cpp b/llvm/lib/CodeGen/StackMaps.cpp index 90aa93e442cf3..eca640ef9ad64 100644 --- a/llvm/lib/CodeGen/StackMaps.cpp +++ b/llvm/lib/CodeGen/StackMaps.cpp @@ -277,7 +277,8 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI, assert(MOI->getReg().isPhysical() && "Virtreg operands should have been rewritten before now."); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(MOI->getReg()); + const TargetRegisterClass *RC = + TRI->getMinimalPhysRegClass(MOI->getReg(), AP.MF->getRegInfo()); assert(!MOI->getSubReg() && "Physical subreg still around."); unsigned Offset = 0; @@ -373,7 +374,8 @@ void StackMaps::print(raw_ostream &OS) { StackMaps::LiveOutReg StackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const { unsigned DwarfRegNum = getDwarfRegNum(Reg, TRI); - unsigned Size = TRI->getSpillSize(*TRI->getMinimalPhysRegClass(Reg)); + unsigned Size = + TRI->getSpillSize(*TRI->getMinimalPhysRegClass(Reg, AP.MF->getRegInfo())); return LiveOutReg(Reg, DwarfRegNum, Size); } diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp index 5ed67bd0a121e..e42c4f1348ab7 100644 --- a/llvm/lib/CodeGen/TailDuplicator.cpp +++ b/llvm/lib/CodeGen/TailDuplicator.cpp @@ -417,7 +417,7 @@ void TailDuplicator::duplicateInstruction( const TargetRegisterClass *ConstrRC; if (VI->second.SubReg != 0) { ConstrRC = TRI->getMatchingSuperRegClass(MappedRC, OrigRC, - VI->second.SubReg); + VI->second.SubReg, *MRI); if (ConstrRC) { // The actual constraining (as in "find appropriate new class") // is done by getMatchingSuperRegClass, so now we only need to diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 9990556f89ed8..9adfa8f839104 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1365,7 +1365,8 @@ TargetLoweringBase::findRepresentativeClass(const TargetRegisterInfo *TRI, for (unsigned i : SuperRegRC.set_bits()) { const TargetRegisterClass *SuperRC = TRI->getRegClass(i); // We want the largest possible spill size. - if (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC)) + if (SuperRC->isSynthetic() || + (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC))) continue; if (!isLegalRC(*TRI, *SuperRC)) continue; diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index c9503fcb77bb2..7c24748acdd93 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -193,14 +193,15 @@ Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo, /// getAllocatableClass - Return the maximal subclass of the given register /// class that is alloctable, or NULL. const TargetRegisterClass * -TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const { +TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC, + const MachineRegisterInfo &MRI) const { if (!RC || RC->isAllocatable()) return RC; for (BitMaskClassIterator It(RC->getSubClassMask(), *this); It.isValid(); ++It) { const TargetRegisterClass *SubRC = getRegClass(It.getID()); - if (SubRC->isAllocatable()) + if (SubRC->isAllocatable() && MRI.isEnabled(SubRC)) return SubRC; } return nullptr; @@ -209,8 +210,8 @@ TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const { /// getMinimalPhysRegClass - Returns the Register Class of a physical /// register of the given type, picking the most sub register class of /// the right type that contains this physreg. -const TargetRegisterClass * -TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const { +const TargetRegisterClass *TargetRegisterInfo::getMinimalPhysRegClass( + MCRegister reg, const MachineRegisterInfo &MRI, MVT VT) const { assert(Register::isPhysicalRegister(reg) && "reg must be a physical register"); @@ -219,7 +220,8 @@ TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const { const TargetRegisterClass* BestRC = nullptr; for (const TargetRegisterClass* RC : regclasses()) { if ((VT == MVT::Other || isTypeLegalForClass(*RC, VT)) && - RC->contains(reg) && (!BestRC || BestRC->hasSubClass(RC))) + RC->contains(reg) && MRI.isEnabled(RC) && + (!BestRC || BestRC->hasSubClass(RC))) BestRC = RC; } @@ -227,8 +229,8 @@ TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const { return BestRC; } -const TargetRegisterClass * -TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const { +const TargetRegisterClass *TargetRegisterInfo::getMinimalPhysRegClassLLT( + MCRegister reg, const MachineRegisterInfo &MRI, LLT Ty) const { assert(Register::isPhysicalRegister(reg) && "reg must be a physical register"); @@ -237,7 +239,7 @@ TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const { const TargetRegisterClass *BestRC = nullptr; for (const TargetRegisterClass *RC : regclasses()) { if ((!Ty.isValid() || isTypeLegalForClass(*RC, Ty)) && RC->contains(reg) && - (!BestRC || BestRC->hasSubClass(RC))) + MRI.isEnabled(RC) && (!BestRC || BestRC->hasSubClass(RC))) BestRC = RC; } @@ -248,7 +250,8 @@ TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const { /// registers for the specific register class. static void getAllocatableSetForRC(const MachineFunction &MF, const TargetRegisterClass *RC, BitVector &R){ - assert(RC->isAllocatable() && "invalid for nonallocatable sets"); + assert(RC->isAllocatable() && MF.getRegInfo().isEnabled(RC) && + "invalid for nonallocatable sets"); ArrayRef Order = RC->getRawAllocationOrder(MF); for (MCPhysReg PR : Order) R.set(PR); @@ -257,38 +260,44 @@ static void getAllocatableSetForRC(const MachineFunction &MF, BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC) const { BitVector Allocatable(getNumRegs()); + const MachineRegisterInfo &MRI = MF.getRegInfo(); if (RC) { // A register class with no allocatable subclass returns an empty set. - const TargetRegisterClass *SubClass = getAllocatableClass(RC); + const TargetRegisterClass *SubClass = getAllocatableClass(RC, MRI); if (SubClass) getAllocatableSetForRC(MF, SubClass, Allocatable); } else { for (const TargetRegisterClass *C : regclasses()) - if (C->isAllocatable()) + if (C->isAllocatable() && MRI.isEnabled(C)) getAllocatableSetForRC(MF, C, Allocatable); } // Mask out the reserved registers - const MachineRegisterInfo &MRI = MF.getRegInfo(); const BitVector &Reserved = MRI.getReservedRegs(); Allocatable.reset(Reserved); return Allocatable; } -static inline -const TargetRegisterClass *firstCommonClass(const uint32_t *A, - const uint32_t *B, - const TargetRegisterInfo *TRI) { - for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32) - if (unsigned Common = *A++ & *B++) - return TRI->getRegClass(I + llvm::countr_zero(Common)); +static inline const TargetRegisterClass * +firstCommonClass(const uint32_t *A, const uint32_t *B, + const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI) { + for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32) { + if (unsigned Common = *A++ & *B++) { + const TargetRegisterClass *RC = + TRI->getRegClass(I + llvm::countr_zero(Common)); + if (MRI.isEnabled(RC)) + return RC; + } + } return nullptr; } const TargetRegisterClass * TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A, - const TargetRegisterClass *B) const { + const TargetRegisterClass *B, + const MachineRegisterInfo &MRI) const { // First take care of the trivial cases. if (A == B) return A; @@ -297,13 +306,13 @@ TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A, // Register classes are ordered topologically, so the largest common // sub-class it the common sub-class with the smallest ID. - return firstCommonClass(A->getSubClassMask(), B->getSubClassMask(), this); + return firstCommonClass(A->getSubClassMask(), B->getSubClassMask(), this, + MRI); } -const TargetRegisterClass * -TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, - const TargetRegisterClass *B, - unsigned Idx) const { +const TargetRegisterClass *TargetRegisterInfo::getMatchingSuperRegClass( + const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx, + const MachineRegisterInfo &MRI) const { assert(A && B && "Missing register class"); assert(Idx && "Bad sub-register index"); @@ -312,14 +321,14 @@ TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, if (RCI.getSubReg() == Idx) // The bit mask contains all register classes that are projected into B // by Idx. Find a class that is also a sub-class of A. - return firstCommonClass(RCI.getMask(), A->getSubClassMask(), this); + return firstCommonClass(RCI.getMask(), A->getSubClassMask(), this, MRI); return nullptr; } -const TargetRegisterClass *TargetRegisterInfo:: -getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, - const TargetRegisterClass *RCB, unsigned SubB, - unsigned &PreA, unsigned &PreB) const { +const TargetRegisterClass *TargetRegisterInfo::getCommonSuperRegClass( + const TargetRegisterClass *RCA, unsigned SubA, + const TargetRegisterClass *RCB, unsigned SubB, unsigned &PreA, + unsigned &PreB, const MachineRegisterInfo &MRI) const { assert(RCA && SubA && RCB && SubB && "Invalid arguments"); // Search all pairs of sub-register indices that project into RCA and RCB @@ -352,7 +361,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, for (SuperRegClassIterator IB(RCB, this, true); IB.isValid(); ++IB) { // Check if a common super-register class exists for this index pair. const TargetRegisterClass *RC = - firstCommonClass(IA.getMask(), IB.getMask(), this); + firstCommonClass(IA.getMask(), IB.getMask(), this, MRI); if (!RC || getRegSizeInBits(*RC) < MinSize) continue; @@ -384,7 +393,8 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI, const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) { + unsigned SrcSubReg, + const MachineRegisterInfo &MRI) { // Same register class. if (DefRC == SrcRC) return true; @@ -393,7 +403,7 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI, unsigned SrcIdx, DefIdx; if (SrcSubReg && DefSubReg) { return TRI.getCommonSuperRegClass(SrcRC, SrcSubReg, DefRC, DefSubReg, - SrcIdx, DefIdx) != nullptr; + SrcIdx, DefIdx, MRI) != nullptr; } // At most one of the register is a sub register, make it Src to avoid @@ -405,18 +415,19 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI, // One of the register is a sub register, check if we can get a superclass. if (SrcSubReg) - return TRI.getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg) != nullptr; + return TRI.getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg, MRI) != + nullptr; // Plain copy. - return TRI.getCommonSubClass(DefRC, SrcRC) != nullptr; + return TRI.getCommonSubClass(DefRC, SrcRC, MRI) != nullptr; } -bool TargetRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, - unsigned DefSubReg, - const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const { +bool TargetRegisterInfo::shouldRewriteCopySrc( + const TargetRegisterClass *DefRC, unsigned DefSubReg, + const TargetRegisterClass *SrcRC, unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const { // If this source does not incur a cross register bank copy, use it. - return shareSameRegisterFile(*this, DefRC, DefSubReg, SrcRC, SrcSubReg); + return shareSameRegisterFile(*this, DefRC, DefSubReg, SrcRC, SrcSubReg, MRI); } // Compute target-independent register allocator hints to help eliminate copies. @@ -507,7 +518,7 @@ TargetRegisterInfo::getRegSizeInBits(Register Reg, // The size is not directly available for physical registers. // Instead, we need to access a register class that contains Reg and // get the size of that register class. - RC = getMinimalPhysRegClass(Reg); + RC = getMinimalPhysRegClass(Reg, MRI); assert(RC && "Unable to deduce the register class"); return getRegSizeInBits(*RC); } diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index ebacbc420f858..f38186a892f0e 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1328,9 +1328,8 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, if (UnfoldMCID.getNumDefs() == 1) { // Unfold the load. LLVM_DEBUG(dbgs() << "2addr: UNFOLDING: " << MI); - const TargetRegisterClass *RC = - TRI->getAllocatableClass( - TII->getRegClass(UnfoldMCID, LoadRegIndex, TRI, *MF)); + const TargetRegisterClass *RC = TRI->getAllocatableClass( + TII->getRegClass(UnfoldMCID, LoadRegIndex, TRI, *MF), *MRI); Register Reg = MRI->createVirtualRegister(RC); SmallVector NewMIs; if (!TII->unfoldMemoryOperand(*MF, MI, Reg, @@ -1531,7 +1530,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, if (SubRegB) { if (RegA.isVirtual()) { assert(TRI->getMatchingSuperRegClass(RC, MRI->getRegClass(RegA), - SubRegB) && + SubRegB, *MRI) && "tied subregister must be a truncation"); // The superreg class will not be used to constrain the subreg class. RC = nullptr; diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 5cc612e89162a..f2090ffb04d84 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -3451,7 +3451,8 @@ bool AArch64FrameLowering::assignCalleeSavedSpillSlots( for (auto &CS : CSI) { Register Reg = CS.getReg(); - const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + RegInfo->getMinimalPhysRegClass(Reg, MF.getRegInfo()); unsigned Size = RegInfo->getSpillSize(*RC); Align Alignment(RegInfo->getSpillAlign(*RC)); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 02943b8a4ab15..c8cd27d247374 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -703,15 +703,15 @@ bool AArch64InstrInfo::canInsertSelect(const MachineBasicBlock &MBB, int &FalseCycles) const { // Check register classes. const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); - const TargetRegisterClass *RC = - RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); + const TargetRegisterClass *RC = RI.getCommonSubClass( + MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI); if (!RC) return false; // Also need to check the dest regclass, in case we're trying to optimize // something like: // %1(gpr) = PHI %2(fpr), bb1, %(fpr), bb2 - if (!RI.getCommonSubClass(RC, MRI.getRegClass(DstReg))) + if (!RI.getCommonSubClass(RC, MRI.getRegClass(DstReg), MRI)) return false; // Expanding cbz/tbz requires an extra cycle of latency on the condition. @@ -5557,8 +5557,9 @@ MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl( // This is slightly expensive to compute for physical regs since // getMinimalPhysRegClass is slow. auto getRegClass = [&](unsigned Reg) { - return Register::isVirtualRegister(Reg) ? MRI.getRegClass(Reg) - : TRI.getMinimalPhysRegClass(Reg); + return Register::isVirtualRegister(Reg) + ? MRI.getRegClass(Reg) + : TRI.getMinimalPhysRegClass(Reg, MRI); }; if (DstMO.getSubReg() == 0 && SrcMO.getSubReg() == 0) { diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp index d0adb78b231a7..2583acd67ee1a 100644 --- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -879,7 +879,6 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I, if (RenameReg) { MCRegister RegToRename = getLdStRegOp(*I).getReg(); DefinedInBB.addReg(*RenameReg); - // Return the sub/super register for RenameReg, matching the size of // OriginalReg. auto GetMatchingSubReg = @@ -895,6 +894,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I, std::function UpdateMIs = [this, RegToRename, GetMatchingSubReg, MergeForward](MachineInstr &MI, bool IsDef) { + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); if (IsDef) { bool SeenDef = false; for (unsigned OpIdx = 0; OpIdx < MI.getNumOperands(); ++OpIdx) { @@ -916,7 +916,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I, if (!isRewritableImplicitDef(MI.getOpcode())) continue; MatchingReg = GetMatchingSubReg( - TRI->getMinimalPhysRegClass(MOP.getReg())); + TRI->getMinimalPhysRegClass(MOP.getReg(), MRI)); } MOP.setReg(MatchingReg); SeenDef = true; @@ -936,7 +936,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I, MatchingReg = GetMatchingSubReg(RC); else MatchingReg = GetMatchingSubReg( - TRI->getMinimalPhysRegClass(MOP.getReg())); + TRI->getMinimalPhysRegClass(MOP.getReg(), MRI)); assert(MatchingReg != AArch64::NoRegister && "Cannot find matching regs for renaming"); MOP.setReg(MatchingReg); @@ -1422,7 +1422,8 @@ static bool areCandidatesToMergeOrPair(MachineInstr &FirstMI, MachineInstr &MI, static bool canRenameMOP(const MachineOperand &MOP, const TargetRegisterInfo *TRI) { if (MOP.isReg()) { - auto *RegClass = TRI->getMinimalPhysRegClass(MOP.getReg()); + const MachineRegisterInfo &MRI = MOP.getParent()->getMF()->getRegInfo(); + auto *RegClass = TRI->getMinimalPhysRegClass(MOP.getReg(), MRI); // Renaming registers with multiple disjunct sub-registers (e.g. the // result of a LD3) means that all sub-registers are renamed, potentially // impacting other instructions we did not check. Bail out. @@ -1496,6 +1497,7 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween, // loop. FoundDef = IsDef; + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); // For defs, check if we can rename the first def of RegToRename. if (FoundDef) { // For some pseudo instructions, we might not generate code in the end @@ -1518,7 +1520,7 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween, LLVM_DEBUG(dbgs() << " Cannot rename " << MOP << " in " << MI); return false; } - RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg())); + RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg(), MRI)); } return true; } else { @@ -1531,7 +1533,7 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween, LLVM_DEBUG(dbgs() << " Cannot rename " << MOP << " in " << MI); return false; } - RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg())); + RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg(), MRI)); } } return true; @@ -1577,6 +1579,8 @@ static bool canRenameUntilSecondLoad( return false; } + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); + for (auto &MOP : MI.operands()) { if (!MOP.isReg() || MOP.isDebug() || !MOP.getReg() || !TRI->regsOverlap(MOP.getReg(), RegToRename)) @@ -1585,7 +1589,8 @@ static bool canRenameUntilSecondLoad( LLVM_DEBUG(dbgs() << " Cannot rename " << MOP << " in " << MI); return false; } - RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg())); + RequiredClasses.insert( + TRI->getMinimalPhysRegClass(MOP.getReg(), MRI)); } return true; @@ -1625,7 +1630,7 @@ static std::optional tryToFindRegisterToRename( }); }; - auto *RegClass = TRI->getMinimalPhysRegClass(Reg); + auto *RegClass = TRI->getMinimalPhysRegClass(Reg, RegInfo); for (const MCPhysReg &PR : *RegClass) { if (DefinedInBB.available(PR) && UsedInBetween.available(PR) && !RegInfo.isReserved(PR) && !AnySubOrSuperRegCalleePreserved(PR) && @@ -1653,7 +1658,9 @@ static std::optional findRenameRegForSameLdStRegPair( if (!DebugCounter::shouldExecute(RegRenamingCounter)) return RenameReg; - auto *RegClass = TRI->getMinimalPhysRegClass(getLdStRegOp(FirstMI).getReg()); + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); + auto *RegClass = + TRI->getMinimalPhysRegClass(getLdStRegOp(FirstMI).getReg(), MRI); MachineFunction &MF = *FirstMI.getParent()->getParent(); if (!RegClass || !MF.getRegInfo().tracksLiveness()) return RenameReg; diff --git a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp index 019b64dd871e2..53159742d14ad 100644 --- a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp +++ b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp @@ -208,7 +208,8 @@ const BitVector &GCNRewritePartialRegUses::getAllocatableAndAlignedRegClassMask( BV.resize(TRI->getNumRegClasses()); for (unsigned ClassID = 0; ClassID < TRI->getNumRegClasses(); ++ClassID) { auto *RC = TRI->getRegClass(ClassID); - if (RC->isAllocatable() && TRI->isRegClassAligned(RC, AlignNumBits)) + if (RC->isAllocatable() && MRI->isEnabled(RC) && + TRI->isRegClassAligned(RC, AlignNumBits)) BV.set(ClassID); } } @@ -437,7 +438,7 @@ bool GCNRewritePartialRegUses::rewriteReg(Register Reg) const { if (const TargetRegisterClass *OpDescRC = getOperandRegClass(MO)) { LLVM_DEBUG(dbgs() << TRI->getRegClassName(SubRegRC) << " & " << TRI->getRegClassName(OpDescRC) << " = "); - SubRegRC = TRI->getCommonSubClass(SubRegRC, OpDescRC); + SubRegRC = TRI->getCommonSubClass(SubRegRC, OpDescRC, *MRI); } } diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 5ccf21f76015d..782d29e288e1f 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -16285,7 +16285,8 @@ SITargetLowering::getTargetMMOFlags(const Instruction &I) const { bool SITargetLowering::checkForPhysRegDependency( SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, unsigned &PhysReg, int &Cost) const { + const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, + unsigned &PhysReg, int &Cost) const { if (User->getOpcode() != ISD::CopyToReg) return false; if (!Def->isMachineOpcode()) @@ -16300,8 +16301,8 @@ bool SITargetLowering::checkForPhysRegDependency( const MCInstrDesc &II = TII->get(MDef->getMachineOpcode()); if (II.isCompare() && II.hasImplicitDefOfPhysReg(AMDGPU::SCC)) { PhysReg = AMDGPU::SCC; - const TargetRegisterClass *RC = - TRI->getMinimalPhysRegClass(PhysReg, Def->getSimpleValueType(ResNo)); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass( + PhysReg, MRI, Def->getSimpleValueType(ResNo)); Cost = RC->getCopyCost(); return true; } diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h index 89da4428e3ab0..33ea15834fba2 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.h +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h @@ -530,6 +530,7 @@ class SITargetLowering final : public AMDGPUTargetLowering { bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI, + const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, unsigned &PhysReg, int &Cost) const override; diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index f4b21b7dfac39..c8083ddf9f951 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -2559,7 +2559,7 @@ void SIInstrInfo::reMaterialize(MachineBasicBlock &MBB, const MCInstrDesc &TID = get(NewOpcode); const TargetRegisterClass *NewRC = - RI.getAllocatableClass(getRegClass(TID, 0, &RI, *MF)); + RI.getAllocatableClass(getRegClass(TID, 0, &RI, *MF), MRI); MRI.setRegClass(DestReg, NewRC); UseMO->setReg(DestReg); @@ -4683,7 +4683,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI, if (RI.hasVectorRegisters(RC) && MO.getSubReg()) { const TargetRegisterClass *SubRC = RI.getSubRegisterClass(RC, MO.getSubReg()); - RC = RI.getCompatibleSubRegClass(RC, SubRC, MO.getSubReg()); + RC = RI.getCompatibleSubRegClass(RC, SubRC, MO.getSubReg(), MRI); if (RC) RC = SubRC; } @@ -5665,7 +5665,7 @@ bool SIInstrInfo::isLegalRegOperand(const MachineRegisterInfo &MRI, if (!SuperRC) return false; - DRC = RI.getMatchingSuperRegClass(SuperRC, DRC, MO.getSubReg()); + DRC = RI.getMatchingSuperRegClass(SuperRC, DRC, MO.getSubReg(), MRI); if (!DRC) return false; } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index 4c5978cdc6665..63ebc543d0b27 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -1387,7 +1387,7 @@ inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P, if (!P.SubReg) return RC == &TRC; auto *TRI = MRI.getTargetRegisterInfo(); - return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg); + return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg, MRI); } /// \brief Create RegSubRegPair from a register MachineOperand diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp index 4b13825040ebe..128c17e2a0a0a 100644 --- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp @@ -103,7 +103,7 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock, MachineInstrSpan MIS(I, &SaveBlock); const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass( - Reg, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32); + Reg, MRI, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32); // If this value was already livein, we probably have a direct use of the // incoming register value, so don't kill at the spill point. This happens @@ -135,6 +135,7 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock, const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); const GCNSubtarget &ST = MF.getSubtarget(); const SIRegisterInfo *RI = ST.getRegisterInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); // Restore all registers immediately before the return and any // terminators that precede it. MachineBasicBlock::iterator I = RestoreBlock.getFirstTerminator(); @@ -144,7 +145,7 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock, for (const CalleeSavedInfo &CI : reverse(CSI)) { Register Reg = CI.getReg(); const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass( - Reg, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32); + Reg, MRI, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32); TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI, Register()); @@ -233,7 +234,7 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs( if (SavedRegs.test(Reg)) { const TargetRegisterClass *RC = - TRI->getMinimalPhysRegClass(Reg, MVT::i32); + TRI->getMinimalPhysRegClass(Reg, MRI, MVT::i32); int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC), TRI->getSpillAlign(*RC), true); diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp index 79a7d1cf66c4d..8454636ad0a43 100644 --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -2906,13 +2906,12 @@ SIRegisterInfo::getEquivalentSGPRClass(const TargetRegisterClass *VRC) const { return SRC; } -const TargetRegisterClass * -SIRegisterInfo::getCompatibleSubRegClass(const TargetRegisterClass *SuperRC, - const TargetRegisterClass *SubRC, - unsigned SubIdx) const { +const TargetRegisterClass *SIRegisterInfo::getCompatibleSubRegClass( + const TargetRegisterClass *SuperRC, const TargetRegisterClass *SubRC, + unsigned SubIdx, const MachineRegisterInfo &MRI) const { // Ensure this subregister index is aligned in the super register. const TargetRegisterClass *MatchRC = - getMatchingSuperRegClass(SuperRC, SubRC, SubIdx); + getMatchingSuperRegClass(SuperRC, SubRC, SubIdx, MRI); return MatchRC && MatchRC->hasSubClassEq(SuperRC) ? MatchRC : nullptr; } @@ -2926,10 +2925,9 @@ bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const { } bool SIRegisterInfo::shouldRewriteCopySrc( - const TargetRegisterClass *DefRC, - unsigned DefSubReg, - const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const { + const TargetRegisterClass *DefRC, unsigned DefSubReg, + const TargetRegisterClass *SrcRC, unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const { // We want to prefer the smallest register class possible, so we don't want to // stop and rewrite on anything that looks like a subregister // extract. Operations mostly don't care about the super register class, so we @@ -2946,7 +2944,7 @@ bool SIRegisterInfo::shouldRewriteCopySrc( // => %3 = COPY %0 // Plain copy. - return getCommonSubClass(DefRC, SrcRC) != nullptr; + return getCommonSubClass(DefRC, SrcRC, MRI) != nullptr; } bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const { @@ -3121,7 +3119,7 @@ SIRegisterInfo::getConstrainedRegClassForOperand(const MachineOperand &MO, return getRegClassForTypeOnBank(MRI.getType(MO.getReg()), *RB); if (const auto *RC = RCOrRB.dyn_cast()) - return getAllocatableClass(RC); + return getAllocatableClass(RC, MRI); return nullptr; } diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h index 88d5686720985..f732682f42e7b 100644 --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h @@ -264,13 +264,14 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo { /// a register tuple), return null. const TargetRegisterClass * getCompatibleSubRegClass(const TargetRegisterClass *SuperRC, - const TargetRegisterClass *SubRC, - unsigned SubIdx) const; + const TargetRegisterClass *SubRC, unsigned SubIdx, + const MachineRegisterInfo &MRI) const; bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const override; + unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const override; /// \returns True if operands defined with this operand type can accept /// a literal constant (i.e. any 32-bit immediate). diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 9adf758b46c48..a85f4099e81f6 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -933,16 +933,16 @@ bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI, return false; } -bool ARMBaseRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, - unsigned DefSubReg, - const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const { +bool ARMBaseRegisterInfo::shouldRewriteCopySrc( + const TargetRegisterClass *DefRC, unsigned DefSubReg, + const TargetRegisterClass *SrcRC, unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const { // We can't extract an SPR from an arbitary DPR (as opposed to a DPR_VFP2). if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 && SrcRC == &ARM::DPRRegClass && (SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1)) return false; - return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, - SrcRC, SrcSubReg); + return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC, + SrcSubReg, MRI); } diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h index 53803cff8b90a..cdc362d7a91f4 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -237,7 +237,8 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo { bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const override; + unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const override; int getSEHRegNum(unsigned i) const { return getEncodingValue(i); } diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index 1c8213b668f71..ace5207488026 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -124,7 +124,8 @@ bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, const AVRSubtarget &STI = MF->getSubtarget(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); - const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + TRI.getMinimalPhysRegClass(Reg, MF->getRegInfo()); unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8; assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported."); diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp index 64dd0338bf60e..1b79758a01fc3 100644 --- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp +++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp @@ -253,6 +253,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters( const AVRSubtarget &STI = MF.getSubtarget(); const TargetInstrInfo &TII = *STI.getInstrInfo(); AVRMachineFunctionInfo *AVRFI = MF.getInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (const CalleeSavedInfo &I : llvm::reverse(CSI)) { Register Reg = I.getReg(); @@ -268,7 +269,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters( break; } - assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 && + assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg, MRI)) == 8 && "Invalid register size"); // Add the callee-saved register as live-in only if it is not already a @@ -301,11 +302,12 @@ bool AVRFrameLowering::restoreCalleeSavedRegisters( const MachineFunction &MF = *MBB.getParent(); const AVRSubtarget &STI = MF.getSubtarget(); const TargetInstrInfo &TII = *STI.getInstrInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (const CalleeSavedInfo &CCSI : CSI) { Register Reg = CCSI.getReg(); - assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 && + assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg, MRI)) == 8 && "Invalid register size"); BuildMI(MBB, MI, DL, TII.get(AVR::POPRd), Reg); diff --git a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp index cedcbff1db24f..fc8e090328d82 100644 --- a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp +++ b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp @@ -468,6 +468,7 @@ bool CSKYFrameLowering::spillCalleeSavedRegisters( MachineFunction *MF = MBB.getParent(); const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); DebugLoc DL; if (MI != MBB.end() && !MI->isDebugInstr()) DL = MI->getDebugLoc(); @@ -475,7 +476,7 @@ bool CSKYFrameLowering::spillCalleeSavedRegisters( for (auto &CS : CSI) { // Insert the spill to the stack frame. Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.storeRegToStackSlot(MBB, MI, Reg, true, CS.getFrameIdx(), RC, TRI, Register()); } @@ -491,13 +492,14 @@ bool CSKYFrameLowering::restoreCalleeSavedRegisters( MachineFunction *MF = MBB.getParent(); const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); DebugLoc DL; if (MI != MBB.end() && !MI->isDebugInstr()) DL = MI->getDebugLoc(); for (auto &CS : reverse(CSI)) { Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI, Register()); assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!"); diff --git a/llvm/lib/Target/Hexagon/BitTracker.cpp b/llvm/lib/Target/Hexagon/BitTracker.cpp index 4d5789a3c5fe1..855e64b4b81c2 100644 --- a/llvm/lib/Target/Hexagon/BitTracker.cpp +++ b/llvm/lib/Target/Hexagon/BitTracker.cpp @@ -712,7 +712,7 @@ BT::BitMask BT::MachineEvaluator::mask(Register Reg, unsigned Sub) const { } uint16_t BT::MachineEvaluator::getPhysRegBitWidth(MCRegister Reg) const { - const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg); + const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg, MRI); return TRI.getRegSizeInBits(PC); } diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp index a027f2cedca0a..d44ea12d154b9 100644 --- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp +++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp @@ -120,7 +120,8 @@ uint16_t HexagonEvaluator::getPhysRegBitWidth(MCRegister Reg) const { return TRI.getRegSizeInBits(RC); } // Default treatment for other physical registers. - if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg)) + if (const TargetRegisterClass *RC = + TRI.getMinimalPhysRegClass(Reg, MF.getRegInfo())) return TRI.getRegSizeInBits(*RC); llvm_unreachable( diff --git a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp index e1005296d6375..e71cc55766a5f 100644 --- a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp +++ b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp @@ -612,7 +612,7 @@ unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO, PhysR = RS.Reg; } MCRegister PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS, *MRI); switch (TRI->getRegSizeInBits(*RC)) { case 32: return IfTrue ? Hexagon::A2_tfrt : Hexagon::A2_tfrf; diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 232651132d6e4..b1ac44a06418c 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -1411,6 +1411,7 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB, return true; } + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (const CalleeSavedInfo &I : CSI) { Register Reg = I.getReg(); // Add live in registers. We treat eh_return callee saved register r0 - r3 @@ -1418,7 +1419,7 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB, // supposed to be killed. bool IsKill = !HRI.isEHReturnCalleeSaveReg(Reg); int FI = I.getFrameIdx(); - const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg, MRI); HII.storeRegToStackSlot(MBB, MI, Reg, IsKill, FI, RC, &HRI, Register()); if (IsKill) MBB.addLiveIn(Reg); @@ -1480,9 +1481,10 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB, return true; } + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (const CalleeSavedInfo &I : CSI) { Register Reg = I.getReg(); - const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg, MRI); int FI = I.getFrameIdx(); HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, &HRI, Register()); } @@ -1560,6 +1562,7 @@ bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector &CSI) const { LLVM_DEBUG(dbgs() << __func__ << " on " << MF.getName() << '\n'); MachineFrameInfo &MFI = MF.getFrameInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); BitVector SRegs(Hexagon::NUM_TARGET_REGS); // Generate a set of unique, callee-saved registers (SRegs), where each @@ -1665,7 +1668,7 @@ bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF, for (const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) { if (!SRegs[S->Reg]) continue; - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg, MRI); int FI = MFI.CreateFixedSpillStackObject(TRI->getSpillSize(*RC), S->Offset); MinOffset = std::min(MinOffset, S->Offset); CSI.push_back(CalleeSavedInfo(S->Reg, FI)); @@ -1677,7 +1680,7 @@ bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF, // such register, create a non-fixed stack object. for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) { Register R = x; - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R, MRI); unsigned Size = TRI->getSpillSize(*RC); int Off = MinOffset - Size; Align Alignment = std::min(TRI->getSpillAlign(*RC), getStackAlign()); diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index b9bf26ba7cca1..20bd79352bae1 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1730,12 +1730,14 @@ bool HexagonInstrInfo::ClobbersPredicate(MachineInstr &MI, std::vector &Pred, bool SkipDead) const { const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo(); + MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); for (const MachineOperand &MO : MI.operands()) { if (MO.isReg()) { if (!MO.isDef()) continue; - const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg()); + const TargetRegisterClass *RC = + HRI.getMinimalPhysRegClass(MO.getReg(), MRI); if (RC == &Hexagon::PredRegsRegClass) { Pred.push_back(MO); return true; diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index 56472d633694a..7c21a12f00db5 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -705,13 +705,14 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI, unsigned predRegNumSrc = 0; unsigned predRegNumDst = 0; const TargetRegisterClass* predRegClass = nullptr; + const MachineRegisterInfo &MRI = PacketMI.getMF()->getRegInfo(); // Get predicate register used in the source instruction. for (auto &MO : PacketMI.operands()) { if (!MO.isReg()) continue; predRegNumSrc = MO.getReg(); - predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc); + predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc, MRI); if (predRegClass == &Hexagon::PredRegsRegClass) break; } @@ -723,7 +724,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI, if (!MO.isReg()) continue; predRegNumDst = MO.getReg(); - predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst); + predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst, MRI); if (predRegClass == &Hexagon::PredRegsRegClass) break; } @@ -1406,6 +1407,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { if (!SUJ->isSucc(SUI)) return true; + const MachineRegisterInfo &MRI = I.getMF()->getRegInfo(); + for (unsigned i = 0; i < SUJ->Succs.size(); ++i) { if (FoundSequentialDependence) break; @@ -1433,7 +1436,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { const TargetRegisterClass *RC = nullptr; if (DepType == SDep::Data) { DepReg = SUJ->Succs[i].getReg(); - RC = HRI->getMinimalPhysRegClass(DepReg); + RC = HRI->getMinimalPhysRegClass(DepReg, MRI); } if (I.isCall() || HII->isJumpR(I) || I.isReturn() || HII->isTailCall(I)) { diff --git a/llvm/lib/Target/Hexagon/RDFCopy.cpp b/llvm/lib/Target/Hexagon/RDFCopy.cpp index b26821cd01718..1f2d2ca88472f 100644 --- a/llvm/lib/Target/Hexagon/RDFCopy.cpp +++ b/llvm/lib/Target/Hexagon/RDFCopy.cpp @@ -48,8 +48,9 @@ bool CopyPropagation::interpretAsCopy(const MachineInstr *MI, EqualityMap &EM) { assert(Register::isPhysicalRegister(DstR.Reg)); assert(Register::isPhysicalRegister(SrcR.Reg)); const TargetRegisterInfo &TRI = DFG.getTRI(); - if (TRI.getMinimalPhysRegClass(DstR.Reg) != - TRI.getMinimalPhysRegClass(SrcR.Reg)) + const MachineRegisterInfo &MRI = DFG.getMF().getRegInfo(); + if (TRI.getMinimalPhysRegClass(DstR.Reg, MRI) != + TRI.getMinimalPhysRegClass(SrcR.Reg, MRI)) return false; if (!DFG.isTracked(SrcR) || !DFG.isTracked(DstR)) return false; @@ -158,7 +159,8 @@ bool CopyPropagation::run() { auto MinPhysReg = [this] (RegisterRef RR) -> unsigned { const TargetRegisterInfo &TRI = DFG.getTRI(); - const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg); + const TargetRegisterClass &RC = + *TRI.getMinimalPhysRegClass(RR.Reg, DFG.getMF().getRegInfo()); if ((RC.LaneMask & RR.Mask) == RC.LaneMask) return RR.Reg; for (MCSubRegIndexIterator S(RR.Reg, &TRI); S.isValid(); ++S) diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp index dc2d61a6e4740..063ae2490417e 100644 --- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp @@ -463,7 +463,8 @@ bool LoongArchFrameLowering::spillCalleeSavedRegisters( // LoongArchTargetLowering::lowerRETURNADDR, don't set kill flag. bool IsKill = !(Reg == LoongArch::R1 && MF->getFrameInfo().isReturnAddressTaken()); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = + TRI->getMinimalPhysRegClass(Reg, MF->getRegInfo()); TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, CS.getFrameIdx(), RC, TRI, Register()); } diff --git a/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/llvm/lib/Target/Mips/MipsFrameLowering.cpp index 99d225f9abfe8..b152d70f7970b 100644 --- a/llvm/lib/Target/Mips/MipsFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsFrameLowering.cpp @@ -114,6 +114,7 @@ bool MipsFrameLowering::hasBP(const MachineFunction &MF) const { uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); int64_t Size = 0; @@ -124,7 +125,7 @@ uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const { // Conservatively assume all callee-saved registers will be saved. for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) { - unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R)); + unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R, MRI)); Size = alignTo(Size + RegSize, RegSize); } diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp index 38f6889a52358..a923d21de8fcf 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -259,7 +259,8 @@ bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, // copy dst_hi, $vr1 unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); - const TargetRegisterClass *DstRC = RegInfo.getMinimalPhysRegClass(Dst); + const TargetRegisterClass *DstRC = + RegInfo.getMinimalPhysRegClass(Dst, MBB.getParent()->getRegInfo()); unsigned VRegSize = RegInfo.getRegSizeInBits(*DstRC) / 16; const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize); Register VR0 = MRI.createVirtualRegister(RC); @@ -796,6 +797,7 @@ bool MipsSEFrameLowering::spillCalleeSavedRegisters( ArrayRef CSI, const TargetRegisterInfo *TRI) const { MachineFunction *MF = MBB.getParent(); const TargetInstrInfo &TII = *STI.getInstrInfo(); + const MachineRegisterInfo &MRI = MF->getRegInfo(); for (const CalleeSavedInfo &I : CSI) { // Add the callee-saved register as live-in. Do not add if the register is @@ -831,7 +833,7 @@ bool MipsSEFrameLowering::spillCalleeSavedRegisters( // Insert the spill to the stack frame. bool IsKill = !IsRAAndRetAddrIsTaken; - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC, TRI, Register()); } diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp index 6dcb59a3a57f8..e697920f94854 100644 --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -2502,7 +2502,7 @@ bool PPCFrameLowering::spillCalleeSavedRegisters( } Spilled.set(Dst); } else { - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); // Use !IsLiveIn for the kill flag. // We do not want to kill registers that are live in this function // before their use because they will become undefined registers. @@ -2605,6 +2605,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters( bool CR4Spilled = false; unsigned CSIIndex = 0; BitVector Restored(TRI->getNumRegs()); + const MachineRegisterInfo &MRI = MF->getRegInfo(); // Initialize insertion-point logic; we will be restoring in reverse // order of spill. @@ -2677,7 +2678,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters( } else { // Default behavior for non-CR saves. - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); // Functions without NoUnwind need to preserve the order of elements in // saved vector registers. diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index 5f5eb31a5a85f..fe8df2a601233 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1526,8 +1526,8 @@ bool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB, // Check register classes. const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); - const TargetRegisterClass *RC = - RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); + const TargetRegisterClass *RC = RI.getCommonSubClass( + MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI); if (!RC) return false; @@ -1559,8 +1559,8 @@ void PPCInstrInfo::insertSelect(MachineBasicBlock &MBB, // Get the register classes. MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); - const TargetRegisterClass *RC = - RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); + const TargetRegisterClass *RC = RI.getCommonSubClass( + MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI); assert(RC && "TrueReg and FalseReg must have overlapping register classes"); bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) || diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 0f450a4bf9692..74073f2f07f48 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -456,6 +456,7 @@ bool PPCRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) co const PPCInstrInfo *InstrInfo = Subtarget.getInstrInfo(); const MachineFrameInfo &MFI = MF.getFrameInfo(); const std::vector &Info = MFI.getCalleeSavedInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); LLVM_DEBUG(dbgs() << "requiresFrameIndexScavenging for " << MF.getName() << ".\n"); @@ -486,7 +487,7 @@ bool PPCRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) co int FrIdx = CSI.getFrameIdx(); Register Reg = CSI.getReg(); - const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, MRI); unsigned Opcode = InstrInfo->getStoreOpcodeForSpill(RC); if (!MFI.isFixedObjectIndex(FrIdx)) { // This is not a fixed object. If it requires alignment then we may still diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 8bac41372b5a8..8010da5dc5634 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -1391,10 +1391,11 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots( MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (auto &CS : CSI) { unsigned Reg = CS.getReg(); - const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg, MRI); unsigned Size = RegInfo->getSpillSize(*RC); // This might need a fixed stack slot. @@ -1483,10 +1484,11 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( // Manually spill values not spilled by libcall & Push/Pop. const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI); + const MachineRegisterInfo &MRI = MF->getRegInfo(); for (auto &CS : UnmanagedCSI) { // Insert the spill to the stack frame. Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg), CS.getFrameIdx(), RC, TRI, Register()); } @@ -1513,9 +1515,10 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters( // load-to-use data hazard between loading RA and return by RA. // loadRegFromStackSlot can insert multiple instructions. const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI); + const MachineRegisterInfo &MRI = MF->getRegInfo(); for (auto &CS : UnmanagedCSI) { Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI, Register()); assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!"); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 10bf1e88d7414..f6bf254cd81c5 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -555,7 +555,7 @@ bool RISCVRegisterInfo::needsFrameBaseReg(MachineInstr *MI, BitVector ReservedRegs = getReservedRegs(MF); for (const MCPhysReg *R = MRI.getCalleeSavedRegs(); MCPhysReg Reg = *R; ++R) { if (!ReservedRegs.test(Reg)) - CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg)); + CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg, MRI)); } int64_t MaxFPOffset = Offset - CalleeSavedSize; diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 80c994a32ea96..a1b023618aa36 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -185,6 +185,7 @@ bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots( unsigned LowGPR = 0; unsigned HighGPR = SystemZ::R15D; int StartSPOffset = SystemZMC::ELFCallFrameSize; + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (auto &CS : CSI) { Register Reg = CS.getReg(); int Offset = getRegSpillOffset(MF, Reg); @@ -227,7 +228,7 @@ bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots( if (CS.getFrameIdx() != INT32_MAX) continue; Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); unsigned Size = TRI->getSpillSize(*RC); CurrOffset -= Size; assert(CurrOffset % 8 == 0 && @@ -1009,6 +1010,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots( int LowSpillOffset = INT32_MAX; Register HighGPR = 0; int HighOffset = -1; + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (auto &CS : CSI) { Register Reg = CS.getReg(); @@ -1038,7 +1040,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots( } } else { Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); Align Alignment = TRI->getSpillAlign(*RC); unsigned Size = TRI->getSpillSize(*RC); Alignment = std::min(Alignment, getStackAlign()); diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 2a6dce863c28f..d4dae31f888be 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -548,8 +548,8 @@ bool SystemZInstrInfo::canInsertSelect(const MachineBasicBlock &MBB, // Check register classes. const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); - const TargetRegisterClass *RC = - RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); + const TargetRegisterClass *RC = RI.getCommonSubClass( + MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI); if (!RC) return false; diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp index d246d3f3c5bd1..2e6bc82d4849e 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -146,12 +146,11 @@ bool SystemZRegisterInfo::getRegAllocationHints( Use.getOpcode() == SystemZ::SELRMux) { MachineOperand &TrueMO = Use.getOperand(1); MachineOperand &FalseMO = Use.getOperand(2); - const TargetRegisterClass *RC = - TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI), - getRC32(TrueMO, VRM, MRI)); + const TargetRegisterClass *RC = TRI->getCommonSubClass( + getRC32(FalseMO, VRM, MRI), getRC32(TrueMO, VRM, MRI), *MRI); if (Use.getOpcode() == SystemZ::SELRMux) - RC = TRI->getCommonSubClass(RC, - getRC32(Use.getOperand(0), VRM, MRI)); + RC = TRI->getCommonSubClass( + RC, getRC32(Use.getOperand(0), VRM, MRI), *MRI); if (RC && RC != &SystemZ::GRX32BitRegClass) { addHints(Order, Hints, RC, MRI); // Return true to make these hints the only regs available to diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp index 32a4accd040eb..614ecca890827 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -64,7 +64,7 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB, const TargetRegisterClass *RC = Register::isVirtualRegister(DestReg) ? MRI.getRegClass(DestReg) - : MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(DestReg); + : MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(DestReg, MRI); unsigned CopyOpcode = WebAssembly::getCopyOpcodeForRegClass(RC); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp index 1e2bee7a5c73b..51a1997a52d36 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp @@ -80,7 +80,7 @@ bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { continue; // Replace explicit uses of the physical register with a virtual register. - const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg); + const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg, MRI); unsigned VReg = WebAssembly::NoRegister; for (MachineOperand &MO : llvm::make_early_inc_range(MRI.reg_operands(PReg))) { diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index d914e1b61ab07..0e0e30877fe1d 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2882,6 +2882,7 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots( } } + const MachineRegisterInfo &MRI = MF.getRegInfo(); // Assign slots for GPRs. It increases frame size. for (CalleeSavedInfo &I : llvm::reverse(CSI)) { Register Reg = I.getReg(); @@ -2931,7 +2932,7 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots( if (X86::VK16RegClass.contains(Reg)) VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1; - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT); unsigned Size = TRI->getSpillSize(*RC); Align Alignment = TRI->getSpillAlign(*RC); // ensure alignment @@ -3018,6 +3019,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters( .setMIFlag(MachineInstr::FrameSetup); } + const MachineRegisterInfo &MRI = MF.getRegInfo(); // Make XMM regs spilled. X86 does not have ability of push/pop XMM. // It can be done by spilling XMMs to stack frame. for (const CalleeSavedInfo &I : llvm::reverse(CSI)) { @@ -3032,7 +3034,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters( // Add the callee-saved register as live-in. It's killed at the spill. MBB.addLiveIn(Reg); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT); TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC, TRI, Register()); @@ -3097,6 +3099,7 @@ bool X86FrameLowering::restoreCalleeSavedRegisters( } DebugLoc DL = MBB.findDebugLoc(MI); + const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); // Reload XMMs from stack frame. for (const CalleeSavedInfo &I : CSI) { @@ -3109,7 +3112,7 @@ bool X86FrameLowering::restoreCalleeSavedRegisters( if (X86::VK16RegClass.contains(Reg)) VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1; - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT); TII.loadRegFromStackSlot(MBB, MI, Reg, I.getFrameIdx(), RC, TRI, Register()); } diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index eb42a4b2119d5..dc2b6514dcfcd 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -4028,8 +4028,8 @@ bool X86InstrInfo::canInsertSelect(const MachineBasicBlock &MBB, // Check register classes. const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); - const TargetRegisterClass *RC = - RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); + const TargetRegisterClass *RC = RI.getCommonSubClass( + MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI); if (!RC) return false; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index be0cf1596d0d9..32c4ee88459d9 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -93,17 +93,16 @@ X86RegisterInfo::getSubClassWithSubReg(const TargetRegisterClass *RC, return X86GenRegisterInfo::getSubClassWithSubReg(RC, Idx); } -const TargetRegisterClass * -X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, - const TargetRegisterClass *B, - unsigned SubIdx) const { +const TargetRegisterClass *X86RegisterInfo::getMatchingSuperRegClass( + const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned SubIdx, + const MachineRegisterInfo &MRI) const { // The sub_8bit sub-register index is more constrained in 32-bit mode. if (!Is64Bit && SubIdx == X86::sub_8bit) { A = X86GenRegisterInfo::getSubClassWithSubReg(A, X86::sub_8bit_hi); if (!A) return nullptr; } - return X86GenRegisterInfo::getMatchingSuperRegClass(A, B, SubIdx); + return X86GenRegisterInfo::getMatchingSuperRegClass(A, B, SubIdx, MRI); } const TargetRegisterClass * @@ -218,10 +217,10 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF, } } -bool X86RegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, - unsigned DefSubReg, - const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const { +bool X86RegisterInfo::shouldRewriteCopySrc( + const TargetRegisterClass *DefRC, unsigned DefSubReg, + const TargetRegisterClass *SrcRC, unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const { // Prevent rewriting a copy where the destination size is larger than the // input size. See PR41619. // FIXME: Should this be factored into the base implementation somehow. @@ -229,8 +228,8 @@ bool X86RegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, SrcRC->hasSuperClassEq(&X86::GR64RegClass) && SrcSubReg == X86::sub_32bit) return false; - return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, - SrcRC, SrcSubReg); + return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC, + SrcSubReg, MRI); } const TargetRegisterClass * diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h index 7296a5f021e4a..e61defefbdf3f 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.h +++ b/llvm/lib/Target/X86/X86RegisterInfo.h @@ -62,8 +62,8 @@ class X86RegisterInfo final : public X86GenRegisterInfo { /// specified sub-register index which is in the specified register class B. const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, - const TargetRegisterClass *B, - unsigned Idx) const override; + const TargetRegisterClass *B, unsigned Idx, + const MachineRegisterInfo &MRI) const override; const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, @@ -76,7 +76,8 @@ class X86RegisterInfo final : public X86GenRegisterInfo { bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const override; + unsigned SrcSubReg, + const MachineRegisterInfo &MRI) const override; /// getPointerRegClass - Returns a TargetRegisterClass used for pointer /// values. diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp index 8cb9413f96526..ea05ea2078c7b 100644 --- a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp @@ -422,6 +422,7 @@ bool XCoreFrameLowering::spillCalleeSavedRegisters( const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); XCoreFunctionInfo *XFI = MF->getInfo(); bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); + const MachineRegisterInfo &MRI = MF->getRegInfo(); DebugLoc DL; if (MI != MBB.end() && !MI->isDebugInstr()) @@ -434,7 +435,7 @@ bool XCoreFrameLowering::spillCalleeSavedRegisters( // Add the callee-saved register as live-in. It's killed at the spill. MBB.addLiveIn(Reg); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC, TRI, Register()); if (emitFrameMoves) { @@ -453,6 +454,7 @@ bool XCoreFrameLowering::restoreCalleeSavedRegisters( const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); bool AtStart = MI == MBB.begin(); MachineBasicBlock::iterator BeforeI = MI; + const MachineRegisterInfo &MRI = MF->getRegInfo(); if (!AtStart) --BeforeI; for (const CalleeSavedInfo &CSR : CSI) { @@ -460,7 +462,7 @@ bool XCoreFrameLowering::restoreCalleeSavedRegisters( assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && "LR & FP are always handled in emitEpilogue"); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI); TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, TRI, Register()); assert(MI != MBB.begin() && diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc index 7de7eabdd1f60..8db39e384dea1 100644 --- a/llvm/unittests/CodeGen/MFCommon.inc +++ b/llvm/unittests/CodeGen/MFCommon.inc @@ -17,12 +17,50 @@ public: bool hasFP(const MachineFunction &MF) const override { return false; } }; -static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr}; +// Dummy regclass fields ... +namespace { +enum { + NoRegister, + GPR0 = 1, + NUM_TARGET_REGS +}; + +enum { + GPRsRegClassID = 0, +}; + +const MCPhysReg GPRs[] = {GPR0}; + +const uint8_t GPRsBits[] = { 0x00 }; + +static const uint32_t GPRsSubClassMask[] = { + 0x00000001, +}; +} // namespace + +static const TargetRegisterClass *const NullRegClasses[] = { nullptr }; +static const MCRegisterClass BogusMCRegisterClasses[] = {{ GPRs, GPRsBits, 0, 1, + sizeof(GPRsBits), GPRsRegClassID, 1, -1, false, true ,false }}; +static const TargetRegisterClass GPRsRegClass = { + &BogusMCRegisterClasses[GPRsRegClassID], + GPRsSubClassMask, + 0, + LaneBitmask(0x0000000000000001), + 0, + false, + 0x0, + false, + false, + NullRegClasses, + nullptr +}; + + static const TargetRegisterClass *const BogusRegisterClasses[] = {&GPRsRegClass}; class BogusRegisterInfo : public TargetRegisterInfo { public: BogusRegisterInfo() - : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses, + : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses+1, nullptr, nullptr, LaneBitmask(~0u), nullptr, nullptr) { InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr); diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp index 49da0c38eefdc..3bac28324db13 100644 --- a/llvm/unittests/CodeGen/MachineInstrTest.cpp +++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -530,8 +530,17 @@ TEST(MachineInstrTest, SpliceOperands) { EXPECT_EQ(MI->getOperand(8).getImm(), MachineOperand::CreateImm(4).getImm()); // test tied operands - MCRegisterClass MRC{ - 0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true}; + MCRegisterClass MRC{0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /*Allocatable=*/true, + /*BaseClass=*/true, + /*Synthetic=*/false}; TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0}; // MachineRegisterInfo will be very upset if these registers aren't // allocatable. diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp index 40af0d3077b2d..e72ada51d2bc0 100644 --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -818,6 +818,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) BitInit *Bit = cast(TSF->getBit(I)); TSFlags |= uint8_t(Bit->getValue()) << I; } + + Synthetic = R->getValueAsBit("Synthetic"); } // Create an inferred register class that was missing from the .td files. @@ -828,7 +830,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, : Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)), TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI), CopyCost(0), Allocatable(true), AllocationPriority(0), - GlobalPriority(false), TSFlags(0) { + GlobalPriority(false), TSFlags(0), Synthetic(false) { Artificial = true; GeneratePressureSet = false; for (const auto R : Members) { @@ -1096,7 +1098,8 @@ CodeGenRegisterClass::getMatchingSubClassWithSubRegs( for (auto *SuperRegRC : SuperRegRCs) { for (const auto &SuperRegClassPair : SuperRegClasses) { const BitVector &SuperRegClassBV = SuperRegClassPair.second; - if (SuperRegClassBV[SuperRegRC->EnumValue]) { + if (SuperRegClassBV[SuperRegRC->EnumValue] && + !SuperRegClassPair.first->Synthetic) { SubRegRC = SuperRegClassPair.first; ChosenSuperRegClass = SuperRegRC; diff --git a/llvm/utils/TableGen/CodeGenRegisters.h b/llvm/utils/TableGen/CodeGenRegisters.h index c34f376ea99db..d53682417fc54 100644 --- a/llvm/utils/TableGen/CodeGenRegisters.h +++ b/llvm/utils/TableGen/CodeGenRegisters.h @@ -333,6 +333,7 @@ class CodeGenRegisterClass { uint8_t AllocationPriority; bool GlobalPriority; uint8_t TSFlags; + bool Synthetic; /// Contains the combination of the lane masks of all subregisters. LaneBitmask LaneMask; /// True if there are at least 2 subregisters which do not interfere. diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index d074e31c62458..041983de18248 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1065,7 +1065,8 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << ", " << RCBitsSize << ", " << RC.getQualifiedIdName() << ", " << RegSize << ", " << RC.CopyCost << ", " << (RC.Allocatable ? "true" : "false") << ", " - << (RC.getBaseClassOrder() ? "true" : "false") << " },\n"; + << (RC.getBaseClassOrder() ? "true" : "false") << " ," + << (RC.Synthetic ? "true" : "false") << " },\n"; } OS << "};\n\n";