[llvm] [AMDGPU] Implement wwm-register allocation (PR #86012)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 20 14:22:00 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-debuginfo

Author: Christudasan Devadasan (cdevadas)

<details>
<summary>Changes</summary>

The vgpr-regalloc currently allocates virtual registers
of both wwm-operands and regular vgpr operands together using
the same pool of available VGPRs. With the representational
shortcoming in the LLVM compiler today, we can't represent the
two CFGs and two parellel modes of reg liveness that occur at
the same time. Due to that, incorrect liveness info is being plotted
for wwm-operands during allocation, eventually leading to wrong
spills and splits of liveranges when come short of physical
registers. This incorrect allocation causes runtime issues which
are hard to track.

This patch attempts to fix this problem by ensuring the allocator
will use distinct registers for wwm operands and they won't be
allocated for other vgpr operands.

Due to performance concerns, we can't afford to reserve or partition
the registers statically. This patch rather predetermines the number
of wwm-registers dynamically and computes allocation masks for various
vgpr classes such that distinct registers will appear in the final
allocation order computed for them. In that way, the reg assignment,
spill, and/or split cases of these classes won't have any register
overlap.

---

Patch is 1.11 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86012.diff


148 Files Affected:

- (modified) llvm/include/llvm/CodeGen/LiveStacks.h (+1) 
- (modified) llvm/include/llvm/CodeGen/MachineInstr.h (+5-3) 
- (modified) llvm/include/llvm/CodeGen/MachineRegisterInfo.h (+34) 
- (modified) llvm/include/llvm/CodeGen/RegisterBankInfo.h (+2-1) 
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+1) 
- (modified) llvm/include/llvm/CodeGen/TargetRegisterInfo.h (+20-11) 
- (modified) llvm/include/llvm/MC/MCRegisterInfo.h (+4) 
- (modified) llvm/include/llvm/Target/Target.td (+6) 
- (modified) llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (+9-5) 
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (+4-2) 
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (+5-2) 
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h (+3-1) 
- (modified) llvm/lib/CodeGen/DetectDeadLanes.cpp (+4-4) 
- (modified) llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp (+22-14) 
- (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/LiveStacks.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/MIRParser/MIRParser.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/MachineCSE.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/MachineCombiner.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/MachineInstr.cpp (+12-8) 
- (modified) llvm/lib/CodeGen/MachineRegisterInfo.cpp (+45-3) 
- (modified) llvm/lib/CodeGen/MachineVerifier.cpp (+3-3) 
- (modified) llvm/lib/CodeGen/PeepholeOptimizer.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/PrologEpilogInserter.cpp (+6-3) 
- (modified) llvm/lib/CodeGen/RegAllocGreedy.cpp (+3-2) 
- (modified) llvm/lib/CodeGen/RegisterBank.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/RegisterBankInfo.cpp (+6-4) 
- (modified) llvm/lib/CodeGen/RegisterClassInfo.cpp (+10-1) 
- (modified) llvm/lib/CodeGen/RegisterCoalescer.cpp (+8-8) 
- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (+12-10) 
- (modified) llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (+1-2) 
- (modified) llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (+5-3) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+5-3) 
- (modified) llvm/lib/CodeGen/StackMaps.cpp (+4-2) 
- (modified) llvm/lib/CodeGen/TailDuplicator.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/TargetLoweringBase.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/TargetRegisterInfo.cpp (+52-41) 
- (modified) llvm/lib/CodeGen/TwoAddressInstructionPass.cpp (+3-4) 
- (modified) llvm/lib/Target/AArch64/AArch64FrameLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.cpp (+6-5) 
- (modified) llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp (+16-9) 
- (modified) llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp (+3-2) 
- (modified) llvm/lib/Target/AMDGPU/SIFrameLowering.cpp (+35-13) 
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+4-3) 
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.h (+1) 
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.cpp (+6-7) 
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.h (+1-1) 
- (modified) llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp (+138-47) 
- (modified) llvm/lib/Target/AMDGPU/SILowerWWMCopies.cpp (+4-4) 
- (modified) llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp (+18-10) 
- (modified) llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h (+6-1) 
- (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp (+41-35) 
- (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.h (+9-3) 
- (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.td (+10) 
- (modified) llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp (+6-6) 
- (modified) llvm/lib/Target/ARM/ARMBaseRegisterInfo.h (+2-1) 
- (modified) llvm/lib/Target/AVR/AVRAsmPrinter.cpp (+2-1) 
- (modified) llvm/lib/Target/AVR/AVRFrameLowering.cpp (+4-2) 
- (modified) llvm/lib/Target/CSKY/CSKYFrameLowering.cpp (+4-2) 
- (modified) llvm/lib/Target/Hexagon/BitTracker.cpp (+1-1) 
- (modified) llvm/lib/Target/Hexagon/HexagonBitTracker.cpp (+2-1) 
- (modified) llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp (+1-1) 
- (modified) llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp (+7-4) 
- (modified) llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp (+3-1) 
- (modified) llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp (+6-3) 
- (modified) llvm/lib/Target/Hexagon/RDFCopy.cpp (+5-3) 
- (modified) llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/Mips/MipsFrameLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/Mips/MipsSEFrameLowering.cpp (+4-2) 
- (modified) llvm/lib/Target/PowerPC/PPCFrameLowering.cpp (+3-2) 
- (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.cpp (+4-4) 
- (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp (+2-1) 
- (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+6-3) 
- (modified) llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (+1-1) 
- (modified) llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp (+4-2) 
- (modified) llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp (+2-2) 
- (modified) llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp (+4-5) 
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp (+1-1) 
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp (+1-1) 
- (modified) llvm/lib/Target/X86/X86FrameLowering.cpp (+6-3) 
- (modified) llvm/lib/Target/X86/X86InstrInfo.cpp (+2-2) 
- (modified) llvm/lib/Target/X86/X86RegisterInfo.cpp (+10-11) 
- (modified) llvm/lib/Target/X86/X86RegisterInfo.h (+4-3) 
- (modified) llvm/lib/Target/XCore/XCoreFrameLowering.cpp (+4-2) 
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/image-waterfall-loop-O0.ll (+103-116) 
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-inline-asm.ll (+7-7) 
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.set.inactive.ll (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/atomic_optimizations_pixelshader.ll (+8-7) 
- (modified) llvm/test/CodeGen/AMDGPU/bb-prolog-spill-during-regalloc.ll (+18-21) 
- (modified) llvm/test/CodeGen/AMDGPU/cf-loop-on-constant.ll (+77-107) 
- (modified) llvm/test/CodeGen/AMDGPU/collapse-endcf.ll (+309-354) 
- (modified) llvm/test/CodeGen/AMDGPU/div_i128.ll (+895-924) 
- (modified) llvm/test/CodeGen/AMDGPU/extend-wwm-virt-reg-liveness.mir (+38-43) 
- (modified) llvm/test/CodeGen/AMDGPU/flat-scratch-init.ll (+5-10) 
- (modified) llvm/test/CodeGen/AMDGPU/fold-reload-into-exec.mir (+26-14) 
- (modified) llvm/test/CodeGen/AMDGPU/fold-reload-into-m0.mir (+8-4) 
- (modified) llvm/test/CodeGen/AMDGPU/gfx-callable-return-types.ll (+44-44) 
- (modified) llvm/test/CodeGen/AMDGPU/global_atomics_scan_fadd.ll (+5-5) 
- (modified) llvm/test/CodeGen/AMDGPU/global_atomics_scan_fmax.ll (+3-3) 
- (modified) llvm/test/CodeGen/AMDGPU/global_atomics_scan_fmin.ll (+3-3) 
- (modified) llvm/test/CodeGen/AMDGPU/global_atomics_scan_fsub.ll (+5-5) 
- (modified) llvm/test/CodeGen/AMDGPU/identical-subrange-spill-infloop.ll (+260-262) 
- (modified) llvm/test/CodeGen/AMDGPU/inline-asm.i128.ll (+12-12) 
- (modified) llvm/test/CodeGen/AMDGPU/kernel-vgpr-spill-mubuf-with-voffset.ll (+7-30) 
- (modified) llvm/test/CodeGen/AMDGPU/mubuf-legalize-operands-non-ptr-intrinsics.ll (+277-295) 
- (modified) llvm/test/CodeGen/AMDGPU/mubuf-legalize-operands.ll (+318-341) 
- (modified) llvm/test/CodeGen/AMDGPU/partial-regcopy-and-spill-missed-at-regalloc.ll (+8-8) 
- (modified) llvm/test/CodeGen/AMDGPU/partial-sgpr-to-vgpr-spills.ll (+335-386) 
- (modified) llvm/test/CodeGen/AMDGPU/pei-amdgpu-cs-chain-preserve.mir (+15-19) 
- (modified) llvm/test/CodeGen/AMDGPU/pei-amdgpu-cs-chain.mir (+9-17) 
- (modified) llvm/test/CodeGen/AMDGPU/preserve-wwm-copy-dst-reg.ll (+287-291) 
- (modified) llvm/test/CodeGen/AMDGPU/rem_i128.ll (+1381-1401) 
- (modified) llvm/test/CodeGen/AMDGPU/scc-clobbered-sgpr-to-vmem-spill.ll (+227-230) 
- (modified) llvm/test/CodeGen/AMDGPU/sgpr-spill-dead-frame-in-dbg-value.mir (+9-8) 
- (modified) llvm/test/CodeGen/AMDGPU/sgpr-spill-incorrect-fi-bookkeeping-bug.ll (+1) 
- (modified) llvm/test/CodeGen/AMDGPU/sgpr-spill-no-vgprs.ll (+68-83) 
- (modified) llvm/test/CodeGen/AMDGPU/sgpr-spill-overlap-wwm-reserve.mir (+155-156) 
- (modified) llvm/test/CodeGen/AMDGPU/sgpr-spill-partially-undef.mir (+6-6) 
- (modified) llvm/test/CodeGen/AMDGPU/sgpr-spills-split-regalloc.ll (+27-35) 
- (modified) llvm/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll (+3-3) 
- (modified) llvm/test/CodeGen/AMDGPU/spill-csr-frame-ptr-reg-copy.ll (+6-8) 
- (modified) llvm/test/CodeGen/AMDGPU/spill-reg-tuple-super-reg-use.mir (+10-12) 
- (modified) llvm/test/CodeGen/AMDGPU/spill-sgpr-to-virtual-vgpr.mir (+43-43) 
- (modified) llvm/test/CodeGen/AMDGPU/spill-sgpr-used-for-exec-copy.mir (+4-4) 
- (modified) llvm/test/CodeGen/AMDGPU/spill-vector-superclass.ll (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/spill-vgpr-to-agpr-update-regscavenger.ll (+15-22) 
- (modified) llvm/test/CodeGen/AMDGPU/spill192.mir (+7-7) 
- (modified) llvm/test/CodeGen/AMDGPU/spill224.mir (+8-8) 
- (modified) llvm/test/CodeGen/AMDGPU/spill288.mir (+10-10) 
- (modified) llvm/test/CodeGen/AMDGPU/spill320.mir (+11-11) 
- (modified) llvm/test/CodeGen/AMDGPU/spill352.mir (+12-12) 
- (modified) llvm/test/CodeGen/AMDGPU/spill384.mir (+13-13) 
- (modified) llvm/test/CodeGen/AMDGPU/stacksave_stackrestore.ll (+63-110) 
- (modified) llvm/test/CodeGen/AMDGPU/tied-op-for-wwm-scratch-reg-spill-restore.mir (+8-8) 
- (modified) llvm/test/CodeGen/AMDGPU/vgpr-spill-placement-issue61083.ll (+14-21) 
- (modified) llvm/test/CodeGen/AMDGPU/whole-wave-register-copy.ll (+10-12) 
- (modified) llvm/test/CodeGen/AMDGPU/whole-wave-register-spill.ll (+24-28) 
- (modified) llvm/test/CodeGen/AMDGPU/wwm-reserved-spill.ll (+226-245) 
- (modified) llvm/test/CodeGen/AMDGPU/wwm-reserved.ll (+138-220) 
- (modified) llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll.expected (+2-2) 
- (modified) llvm/unittests/CodeGen/MFCommon.inc (+40-2) 
- (modified) llvm/unittests/CodeGen/MachineInstrTest.cpp (+11-2) 
- (modified) llvm/utils/TableGen/CodeGenRegisters.cpp (+5-2) 
- (modified) llvm/utils/TableGen/CodeGenRegisters.h (+1) 
- (modified) llvm/utils/TableGen/RegisterInfoEmitter.cpp (+2-1) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 2edc2985f0ee66..b9e55987383901 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 fcdd73d8b65fdd..c7067d90a3ce06 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 09d9a0b4ec402f..78414f31d1bf82 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -94,6 +94,16 @@ class MachineRegisterInfo {
   /// all registers that were disabled are removed from the list.
   SmallVector<MCPhysReg, 16> UpdatedCSRs;
 
+  /// The Synthetic field of regclasses. Targets can alter this vector
+  /// to enable classes dynamically during codegen.
+  BitVector RegClassSyntheticInfo;
+
+  /// To have more restrictions on the allocation order for each register class.
+  /// For some targets, two distinct register classes can have the same set of
+  /// registers, but their allocatable set can vary. This vector helps targets
+  /// to dynamically determine the actual allocatable set for RCs.
+  std::vector<BitVector> RegClassAllocationMasks;
+
   /// 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 +267,30 @@ class MachineRegisterInfo {
   /// Notice that it will override ant previously disabled/saved CSRs.
   void setCalleeSavedRegs(ArrayRef<MCPhysReg> 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;
+
+  /// Update dynamically determined allocation mask for register classes.
+  void updateAllocationMaskForRCs(std::vector<BitVector> &&Mask);
+
+  // Return the allocation mask for regclass \p RC.
+  const BitVector &getAllocationMaskForRC(const TargetRegisterClass &RC) const;
+
+  /// True when the target has dynamically determined allocation mask for its
+  /// register classes.
+  bool hasAllocationMaskForRCs() const {
+    return RegClassAllocationMasks.size();
+  }
+
   // 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 62c4a57a605d68..117f381512a1c6 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 59fad88f91b1d1..5ef963cae55286 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 117d3f71829747..a3d68d6743ede5 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 fb4d11ec1d4d16..1a2ff58c31f5a6 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 cb1c0ed2513d45..0cf9159030bc52 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -338,6 +338,12 @@ class RegisterClass<string namespace, list<ValueType> 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 ed6ce6bc73d38c..93860aae8acfdf 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<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
   if (Order.empty()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 14f2a363f9be61..7b403fee7ed120 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 6b5ad62e083e3b..0b372d7b0e1bf1 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 a74d43897d45b3..6d4794d27effbd 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 667a9efc6f6c04..70ab73b5996b48 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,
                      unsign...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/86012


More information about the llvm-commits mailing list