Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:29

0001 //===- LiveRegMatrix.h - Track register interference ----------*- C++ -*---===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // The LiveRegMatrix analysis pass keeps track of virtual register interference
0010 // along two dimensions: Slot indexes and register units. The matrix is used by
0011 // register allocators to ensure that no interfering virtual registers get
0012 // assigned to overlapping physical registers.
0013 //
0014 // Register units are defined in MCRegisterInfo.h, they represent the smallest
0015 // unit of interference when dealing with overlapping physical registers. The
0016 // LiveRegMatrix is represented as a LiveIntervalUnion per register unit. When
0017 // a virtual register is assigned to a physical register, the live range for
0018 // the virtual register is inserted into the LiveIntervalUnion for each regunit
0019 // in the physreg.
0020 //
0021 //===----------------------------------------------------------------------===//
0022 
0023 #ifndef LLVM_CODEGEN_LIVEREGMATRIX_H
0024 #define LLVM_CODEGEN_LIVEREGMATRIX_H
0025 
0026 #include "llvm/ADT/BitVector.h"
0027 #include "llvm/CodeGen/LiveIntervalUnion.h"
0028 #include "llvm/CodeGen/MachineFunctionPass.h"
0029 #include <memory>
0030 
0031 namespace llvm {
0032 
0033 class AnalysisUsage;
0034 class LiveInterval;
0035 class LiveIntervals;
0036 class MachineFunction;
0037 class TargetRegisterInfo;
0038 class VirtRegMap;
0039 
0040 class LiveRegMatrix {
0041   friend class LiveRegMatrixWrapperLegacy;
0042   friend class LiveRegMatrixAnalysis;
0043   const TargetRegisterInfo *TRI = nullptr;
0044   LiveIntervals *LIS = nullptr;
0045   VirtRegMap *VRM = nullptr;
0046 
0047   // UserTag changes whenever virtual registers have been modified.
0048   unsigned UserTag = 0;
0049 
0050   // The matrix is represented as a LiveIntervalUnion per register unit.
0051   std::unique_ptr<LiveIntervalUnion::Allocator> LIUAlloc;
0052   LiveIntervalUnion::Array Matrix;
0053 
0054   // Cached queries per register unit.
0055   std::unique_ptr<LiveIntervalUnion::Query[]> Queries;
0056 
0057   // Cached register mask interference info.
0058   unsigned RegMaskTag = 0;
0059   unsigned RegMaskVirtReg = 0;
0060   BitVector RegMaskUsable;
0061 
0062   LiveRegMatrix()
0063       : LIUAlloc(std::make_unique<LiveIntervalUnion::Allocator>()) {};
0064   void releaseMemory();
0065 
0066 public:
0067   LiveRegMatrix(LiveRegMatrix &&Other) = default;
0068 
0069   void init(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM);
0070 
0071   //===--------------------------------------------------------------------===//
0072   // High-level interface.
0073   //===--------------------------------------------------------------------===//
0074   //
0075   // Check for interference before assigning virtual registers to physical
0076   // registers.
0077   //
0078 
0079   /// Invalidate cached interference queries after modifying virtual register
0080   /// live ranges. Interference checks may return stale information unless
0081   /// caches are invalidated.
0082   void invalidateVirtRegs() { ++UserTag; }
0083 
0084   enum InterferenceKind {
0085     /// No interference, go ahead and assign.
0086     IK_Free = 0,
0087 
0088     /// Virtual register interference. There are interfering virtual registers
0089     /// assigned to PhysReg or its aliases. This interference could be resolved
0090     /// by unassigning those other virtual registers.
0091     IK_VirtReg,
0092 
0093     /// Register unit interference. A fixed live range is in the way, typically
0094     /// argument registers for a call. This can't be resolved by unassigning
0095     /// other virtual registers.
0096     IK_RegUnit,
0097 
0098     /// RegMask interference. The live range is crossing an instruction with a
0099     /// regmask operand that doesn't preserve PhysReg. This typically means
0100     /// VirtReg is live across a call, and PhysReg isn't call-preserved.
0101     IK_RegMask
0102   };
0103 
0104   /// Check for interference before assigning VirtReg to PhysReg.
0105   /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg).
0106   /// When there is more than one kind of interference, the InterferenceKind
0107   /// with the highest enum value is returned.
0108   InterferenceKind checkInterference(const LiveInterval &VirtReg,
0109                                      MCRegister PhysReg);
0110 
0111   /// Check for interference in the segment [Start, End) that may prevent
0112   /// assignment to PhysReg. If this function returns true, there is
0113   /// interference in the segment [Start, End) of some other interval already
0114   /// assigned to PhysReg. If this function returns false, PhysReg is free at
0115   /// the segment [Start, End).
0116   bool checkInterference(SlotIndex Start, SlotIndex End, MCRegister PhysReg);
0117 
0118   /// Check for interference in the segment [Start, End) that may prevent
0119   /// assignment to PhysReg, like checkInterference. Returns a lane mask of
0120   /// which lanes of the physical register interfere in the segment [Start, End)
0121   /// of some other interval already assigned to PhysReg.
0122   ///
0123   /// If this function returns LaneBitmask::getNone(), PhysReg is completely
0124   /// free at the segment [Start, End).
0125   LaneBitmask checkInterferenceLanes(SlotIndex Start, SlotIndex End,
0126                                      MCRegister PhysReg);
0127 
0128   /// Assign VirtReg to PhysReg.
0129   /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and
0130   /// update VirtRegMap. The live range is expected to be available in PhysReg.
0131   void assign(const LiveInterval &VirtReg, MCRegister PhysReg);
0132 
0133   /// Unassign VirtReg from its PhysReg.
0134   /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes
0135   /// the assignment and updates VirtRegMap accordingly.
0136   void unassign(const LiveInterval &VirtReg);
0137 
0138   /// Returns true if the given \p PhysReg has any live intervals assigned.
0139   bool isPhysRegUsed(MCRegister PhysReg) const;
0140 
0141   //===--------------------------------------------------------------------===//
0142   // Low-level interface.
0143   //===--------------------------------------------------------------------===//
0144   //
0145   // Provide access to the underlying LiveIntervalUnions.
0146   //
0147 
0148   /// Check for regmask interference only.
0149   /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg.
0150   /// If PhysReg is null, check if VirtReg crosses any regmask operands.
0151   bool checkRegMaskInterference(const LiveInterval &VirtReg,
0152                                 MCRegister PhysReg = MCRegister::NoRegister);
0153 
0154   /// Check for regunit interference only.
0155   /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's
0156   /// register units.
0157   bool checkRegUnitInterference(const LiveInterval &VirtReg,
0158                                 MCRegister PhysReg);
0159 
0160   /// Query a line of the assigned virtual register matrix directly.
0161   /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg.
0162   /// This returns a reference to an internal Query data structure that is only
0163   /// valid until the next query() call.
0164   LiveIntervalUnion::Query &query(const LiveRange &LR, MCRegUnit RegUnit);
0165 
0166   /// Directly access the live interval unions per regunit.
0167   /// This returns an array indexed by the regunit number.
0168   LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; }
0169 
0170   Register getOneVReg(unsigned PhysReg) const;
0171 };
0172 
0173 class LiveRegMatrixWrapperLegacy : public MachineFunctionPass {
0174   LiveRegMatrix LRM;
0175 
0176 public:
0177   static char ID;
0178 
0179   LiveRegMatrixWrapperLegacy() : MachineFunctionPass(ID) {}
0180 
0181   LiveRegMatrix &getLRM() { return LRM; }
0182   const LiveRegMatrix &getLRM() const { return LRM; }
0183 
0184   void getAnalysisUsage(AnalysisUsage &AU) const override;
0185   bool runOnMachineFunction(MachineFunction &MF) override;
0186   void releaseMemory() override;
0187 };
0188 
0189 class LiveRegMatrixAnalysis : public AnalysisInfoMixin<LiveRegMatrixAnalysis> {
0190   friend AnalysisInfoMixin<LiveRegMatrixAnalysis>;
0191   static AnalysisKey Key;
0192 
0193 public:
0194   using Result = LiveRegMatrix;
0195 
0196   LiveRegMatrix run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
0197 };
0198 
0199 } // end namespace llvm
0200 
0201 #endif // LLVM_CODEGEN_LIVEREGMATRIX_H