Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- LiveRangeEdit.h - Basic tools for split and spill --------*- 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 LiveRangeEdit class represents changes done to a virtual register when it
0010 // is spilled or split.
0011 //
0012 // The parent register is never changed. Instead, a number of new virtual
0013 // registers are created and added to the newRegs vector.
0014 //
0015 //===----------------------------------------------------------------------===//
0016 
0017 #ifndef LLVM_CODEGEN_LIVERANGEEDIT_H
0018 #define LLVM_CODEGEN_LIVERANGEEDIT_H
0019 
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/SetVector.h"
0022 #include "llvm/ADT/SmallPtrSet.h"
0023 #include "llvm/ADT/SmallVector.h"
0024 #include "llvm/CodeGen/LiveInterval.h"
0025 #include "llvm/CodeGen/MachineBasicBlock.h"
0026 #include "llvm/CodeGen/MachineFunction.h"
0027 #include "llvm/CodeGen/MachineRegisterInfo.h"
0028 #include "llvm/CodeGen/SlotIndexes.h"
0029 #include "llvm/CodeGen/TargetSubtargetInfo.h"
0030 #include <cassert>
0031 
0032 namespace llvm {
0033 
0034 class LiveIntervals;
0035 class MachineInstr;
0036 class MachineOperand;
0037 class TargetInstrInfo;
0038 class TargetRegisterInfo;
0039 class VirtRegMap;
0040 class VirtRegAuxInfo;
0041 
0042 class LiveRangeEdit : private MachineRegisterInfo::Delegate {
0043 public:
0044   /// Callback methods for LiveRangeEdit owners.
0045   class Delegate {
0046     virtual void anchor();
0047 
0048   public:
0049     virtual ~Delegate() = default;
0050 
0051     /// Called immediately before erasing a dead machine instruction.
0052     virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
0053 
0054     /// Called when a virtual register is no longer used. Return false to defer
0055     /// its deletion from LiveIntervals.
0056     virtual bool LRE_CanEraseVirtReg(Register) { return true; }
0057 
0058     /// Called before shrinking the live range of a virtual register.
0059     virtual void LRE_WillShrinkVirtReg(Register) {}
0060 
0061     /// Called after cloning a virtual register.
0062     /// This is used for new registers representing connected components of Old.
0063     virtual void LRE_DidCloneVirtReg(Register New, Register Old) {}
0064   };
0065 
0066 private:
0067   const LiveInterval *const Parent;
0068   SmallVectorImpl<Register> &NewRegs;
0069   MachineRegisterInfo &MRI;
0070   LiveIntervals &LIS;
0071   VirtRegMap *VRM;
0072   const TargetInstrInfo &TII;
0073   Delegate *const TheDelegate;
0074 
0075   /// FirstNew - Index of the first register added to NewRegs.
0076   const unsigned FirstNew;
0077 
0078   /// ScannedRemattable - true when remattable values have been identified.
0079   bool ScannedRemattable = false;
0080 
0081   /// DeadRemats - The saved instructions which have already been dead after
0082   /// rematerialization but not deleted yet -- to be done in postOptimization.
0083   SmallPtrSet<MachineInstr *, 32> *DeadRemats;
0084 
0085   /// Remattable - Values defined by remattable instructions as identified by
0086   /// tii.isTriviallyReMaterializable().
0087   SmallPtrSet<const VNInfo *, 4> Remattable;
0088 
0089   /// Rematted - Values that were actually rematted, and so need to have their
0090   /// live range trimmed or entirely removed.
0091   SmallPtrSet<const VNInfo *, 4> Rematted;
0092 
0093   /// scanRemattable - Identify the Parent values that may rematerialize.
0094   void scanRemattable();
0095 
0096   /// foldAsLoad - If LI has a single use and a single def that can be folded as
0097   /// a load, eliminate the register by folding the def into the use.
0098   bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr *> &Dead);
0099 
0100   using ToShrinkSet = SmallSetVector<LiveInterval *, 8>;
0101 
0102   /// Helper for eliminateDeadDefs.
0103   void eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink);
0104 
0105   /// MachineRegisterInfo callback to notify when new virtual
0106   /// registers are created.
0107   void MRI_NoteNewVirtualRegister(Register VReg) override;
0108 
0109   /// Check if MachineOperand \p MO is a last use/kill either in the
0110   /// main live range of \p LI or in one of the matching subregister ranges.
0111   bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const;
0112 
0113   /// Create a new empty interval based on OldReg.
0114   LiveInterval &createEmptyIntervalFrom(Register OldReg, bool createSubRanges);
0115 
0116 public:
0117   /// Create a LiveRangeEdit for breaking down parent into smaller pieces.
0118   /// @param parent The register being spilled or split.
0119   /// @param newRegs List to receive any new registers created. This needn't be
0120   ///                empty initially, any existing registers are ignored.
0121   /// @param MF The MachineFunction the live range edit is taking place in.
0122   /// @param lis The collection of all live intervals in this function.
0123   /// @param vrm Map of virtual registers to physical registers for this
0124   ///            function.  If NULL, no virtual register map updates will
0125   ///            be done.  This could be the case if called before Regalloc.
0126   /// @param deadRemats The collection of all the instructions defining an
0127   ///                   original reg and are dead after remat.
0128   LiveRangeEdit(const LiveInterval *parent, SmallVectorImpl<Register> &newRegs,
0129                 MachineFunction &MF, LiveIntervals &lis, VirtRegMap *vrm,
0130                 Delegate *delegate = nullptr,
0131                 SmallPtrSet<MachineInstr *, 32> *deadRemats = nullptr)
0132       : Parent(parent), NewRegs(newRegs), MRI(MF.getRegInfo()), LIS(lis),
0133         VRM(vrm), TII(*MF.getSubtarget().getInstrInfo()), TheDelegate(delegate),
0134         FirstNew(newRegs.size()), DeadRemats(deadRemats) {
0135     MRI.addDelegate(this);
0136   }
0137 
0138   ~LiveRangeEdit() override { MRI.resetDelegate(this); }
0139 
0140   const LiveInterval &getParent() const {
0141     assert(Parent && "No parent LiveInterval");
0142     return *Parent;
0143   }
0144 
0145   Register getReg() const { return getParent().reg(); }
0146 
0147   /// Iterator for accessing the new registers added by this edit.
0148   using iterator = SmallVectorImpl<Register>::const_iterator;
0149   iterator begin() const { return NewRegs.begin() + FirstNew; }
0150   iterator end() const { return NewRegs.end(); }
0151   unsigned size() const { return NewRegs.size() - FirstNew; }
0152   bool empty() const { return size() == 0; }
0153   Register get(unsigned idx) const { return NewRegs[idx + FirstNew]; }
0154 
0155   /// pop_back - It allows LiveRangeEdit users to drop new registers.
0156   /// The context is when an original def instruction of a register is
0157   /// dead after rematerialization, we still want to keep it for following
0158   /// rematerializations. We save the def instruction in DeadRemats,
0159   /// and replace the original dst register with a new dummy register so
0160   /// the live range of original dst register can be shrinked normally.
0161   /// We don't want to allocate phys register for the dummy register, so
0162   /// we want to drop it from the NewRegs set.
0163   void pop_back() { NewRegs.pop_back(); }
0164 
0165   ArrayRef<Register> regs() const { return ArrayRef(NewRegs).slice(FirstNew); }
0166 
0167   /// createFrom - Create a new virtual register based on OldReg.
0168   Register createFrom(Register OldReg);
0169 
0170   /// create - Create a new register with the same class and original slot as
0171   /// parent.
0172   LiveInterval &createEmptyInterval() {
0173     return createEmptyIntervalFrom(getReg(), true);
0174   }
0175 
0176   Register create() { return createFrom(getReg()); }
0177 
0178   /// anyRematerializable - Return true if any parent values may be
0179   /// rematerializable.
0180   /// This function must be called before any rematerialization is attempted.
0181   bool anyRematerializable();
0182 
0183   /// checkRematerializable - Manually add VNI to the list of rematerializable
0184   /// values if DefMI may be rematerializable.
0185   bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI);
0186 
0187   /// Remat - Information needed to rematerialize at a specific location.
0188   struct Remat {
0189     const VNInfo *const ParentVNI;  // parent_'s value at the remat location.
0190     MachineInstr *OrigMI = nullptr; // Instruction defining OrigVNI. It contains
0191                                     // the real expr for remat.
0192 
0193     explicit Remat(const VNInfo *ParentVNI) : ParentVNI(ParentVNI) {}
0194   };
0195 
0196   /// allUsesAvailableAt - Return true if all registers used by OrigMI at
0197   /// OrigIdx are also available with the same value at UseIdx.
0198   bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
0199                           SlotIndex UseIdx) const;
0200 
0201   /// canRematerializeAt - Determine if ParentVNI can be rematerialized at
0202   /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI.
0203   /// When cheapAsAMove is set, only cheap remats are allowed.
0204   bool canRematerializeAt(Remat &RM, VNInfo *OrigVNI, SlotIndex UseIdx,
0205                           bool cheapAsAMove);
0206 
0207   /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
0208   /// instruction into MBB before MI. The new instruction is mapped, but
0209   /// liveness is not updated. If ReplaceIndexMI is not null it will be replaced
0210   /// by new MI in the index map.
0211   /// Return the SlotIndex of the new instruction.
0212   SlotIndex rematerializeAt(MachineBasicBlock &MBB,
0213                             MachineBasicBlock::iterator MI, Register DestReg,
0214                             const Remat &RM, const TargetRegisterInfo &,
0215                             bool Late = false, unsigned SubIdx = 0,
0216                             MachineInstr *ReplaceIndexMI = nullptr);
0217 
0218   /// markRematerialized - explicitly mark a value as rematerialized after doing
0219   /// it manually.
0220   void markRematerialized(const VNInfo *ParentVNI) {
0221     Rematted.insert(ParentVNI);
0222   }
0223 
0224   /// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
0225   bool didRematerialize(const VNInfo *ParentVNI) const {
0226     return Rematted.count(ParentVNI);
0227   }
0228 
0229   /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
0230   /// to erase it from LIS.
0231   void eraseVirtReg(Register Reg);
0232 
0233   /// eliminateDeadDefs - Try to delete machine instructions that are now dead
0234   /// (allDefsAreDead returns true). This may cause live intervals to be trimmed
0235   /// and further dead efs to be eliminated.
0236   /// RegsBeingSpilled lists registers currently being spilled by the register
0237   /// allocator.  These registers should not be split into new intervals
0238   /// as currently those new intervals are not guaranteed to spill.
0239   void eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
0240                          ArrayRef<Register> RegsBeingSpilled = {});
0241 
0242   /// calculateRegClassAndHint - Recompute register class and hint for each new
0243   /// register.
0244   void calculateRegClassAndHint(MachineFunction &, VirtRegAuxInfo &);
0245 };
0246 
0247 } // end namespace llvm
0248 
0249 #endif // LLVM_CODEGEN_LIVERANGEEDIT_H