Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- llvm/CodeGen/VirtRegMap.h - Virtual Register Map ---------*- 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 // This file implements a virtual register map. This maps virtual registers to
0010 // physical registers and virtual registers to stack slots. It is created and
0011 // updated by a register allocator and then used by a machine code rewriter that
0012 // adds spill code and rewrites virtual into physical register references.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_CODEGEN_VIRTREGMAP_H
0017 #define LLVM_CODEGEN_VIRTREGMAP_H
0018 
0019 #include "llvm/ADT/IndexedMap.h"
0020 #include "llvm/CodeGen/MachineFunctionPass.h"
0021 #include "llvm/CodeGen/TargetRegisterInfo.h"
0022 #include "llvm/CodeGen/TileShapeInfo.h"
0023 #include "llvm/IR/PassManager.h"
0024 #include "llvm/Pass.h"
0025 #include <cassert>
0026 
0027 namespace llvm {
0028 
0029 class MachineFunction;
0030 class MachineRegisterInfo;
0031 class raw_ostream;
0032 class TargetInstrInfo;
0033 
0034 class VirtRegMap {
0035   MachineRegisterInfo *MRI = nullptr;
0036   const TargetInstrInfo *TII = nullptr;
0037   const TargetRegisterInfo *TRI = nullptr;
0038   MachineFunction *MF = nullptr;
0039 
0040   /// Virt2PhysMap - This is a virtual to physical register
0041   /// mapping. Each virtual register is required to have an entry in
0042   /// it; even spilled virtual registers (the register mapped to a
0043   /// spilled register is the temporary used to load it from the
0044   /// stack).
0045   IndexedMap<MCRegister, VirtReg2IndexFunctor> Virt2PhysMap;
0046 
0047   /// Virt2StackSlotMap - This is virtual register to stack slot
0048   /// mapping. Each spilled virtual register has an entry in it
0049   /// which corresponds to the stack slot this register is spilled
0050   /// at.
0051   IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
0052 
0053   /// Virt2SplitMap - This is virtual register to splitted virtual register
0054   /// mapping.
0055   IndexedMap<Register, VirtReg2IndexFunctor> Virt2SplitMap;
0056 
0057   /// Virt2ShapeMap - For X86 AMX register whose register is bound shape
0058   /// information.
0059   DenseMap<Register, ShapeT> Virt2ShapeMap;
0060 
0061   /// createSpillSlot - Allocate a spill slot for RC from MFI.
0062   unsigned createSpillSlot(const TargetRegisterClass *RC);
0063 
0064 public:
0065   static constexpr int NO_STACK_SLOT = INT_MAX;
0066 
0067   VirtRegMap() : Virt2StackSlotMap(NO_STACK_SLOT) {}
0068   VirtRegMap(const VirtRegMap &) = delete;
0069   VirtRegMap &operator=(const VirtRegMap &) = delete;
0070   VirtRegMap(VirtRegMap &&) = default;
0071 
0072   void init(MachineFunction &MF);
0073 
0074   MachineFunction &getMachineFunction() const {
0075     assert(MF && "getMachineFunction called before runOnMachineFunction");
0076     return *MF;
0077   }
0078 
0079   MachineRegisterInfo &getRegInfo() const { return *MRI; }
0080   const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
0081 
0082   void grow();
0083 
0084   /// returns true if the specified virtual register is
0085   /// mapped to a physical register
0086   bool hasPhys(Register virtReg) const { return getPhys(virtReg).isValid(); }
0087 
0088   /// returns the physical register mapped to the specified
0089   /// virtual register
0090   MCRegister getPhys(Register virtReg) const {
0091     assert(virtReg.isVirtual());
0092     return Virt2PhysMap[virtReg];
0093   }
0094 
0095   /// creates a mapping for the specified virtual register to
0096   /// the specified physical register
0097   void assignVirt2Phys(Register virtReg, MCRegister physReg);
0098 
0099   bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); }
0100 
0101   bool hasShape(Register virtReg) const {
0102     return Virt2ShapeMap.contains(virtReg);
0103   }
0104 
0105   ShapeT getShape(Register virtReg) const {
0106     assert(virtReg.isVirtual());
0107     return Virt2ShapeMap.lookup(virtReg);
0108   }
0109 
0110   void assignVirt2Shape(Register virtReg, ShapeT shape) {
0111     Virt2ShapeMap[virtReg] = shape;
0112   }
0113 
0114   /// clears the specified virtual register's, physical
0115   /// register mapping
0116   void clearVirt(Register virtReg) {
0117     assert(virtReg.isVirtual());
0118     assert(Virt2PhysMap[virtReg] &&
0119            "attempt to clear a not assigned virtual register");
0120     Virt2PhysMap[virtReg] = MCRegister();
0121   }
0122 
0123   /// clears all virtual to physical register mappings
0124   void clearAllVirt() {
0125     Virt2PhysMap.clear();
0126     grow();
0127   }
0128 
0129   /// returns true if VirtReg is assigned to its preferred physreg.
0130   bool hasPreferredPhys(Register VirtReg) const;
0131 
0132   /// returns true if VirtReg has a known preferred register.
0133   /// This returns false if VirtReg has a preference that is a virtual
0134   /// register that hasn't been assigned yet.
0135   bool hasKnownPreference(Register VirtReg) const;
0136 
0137   /// records virtReg is a split live interval from SReg.
0138   void setIsSplitFromReg(Register virtReg, Register SReg) {
0139     Virt2SplitMap[virtReg] = SReg;
0140     if (hasShape(SReg)) {
0141       Virt2ShapeMap[virtReg] = getShape(SReg);
0142     }
0143   }
0144 
0145   /// returns the live interval virtReg is split from.
0146   Register getPreSplitReg(Register virtReg) const {
0147     return Virt2SplitMap[virtReg];
0148   }
0149 
0150   /// getOriginal - Return the original virtual register that VirtReg descends
0151   /// from through splitting.
0152   /// A register that was not created by splitting is its own original.
0153   /// This operation is idempotent.
0154   Register getOriginal(Register VirtReg) const {
0155     Register Orig = getPreSplitReg(VirtReg);
0156     return Orig ? Orig : VirtReg;
0157   }
0158 
0159   /// returns true if the specified virtual register is not
0160   /// mapped to a stack slot or rematerialized.
0161   bool isAssignedReg(Register virtReg) const {
0162     if (getStackSlot(virtReg) == NO_STACK_SLOT)
0163       return true;
0164     // Split register can be assigned a physical register as well as a
0165     // stack slot or remat id.
0166     return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg]);
0167   }
0168 
0169   /// returns the stack slot mapped to the specified virtual
0170   /// register
0171   int getStackSlot(Register virtReg) const {
0172     assert(virtReg.isVirtual());
0173     return Virt2StackSlotMap[virtReg];
0174   }
0175 
0176   /// create a mapping for the specifed virtual register to
0177   /// the next available stack slot
0178   int assignVirt2StackSlot(Register virtReg);
0179 
0180   /// create a mapping for the specified virtual register to
0181   /// the specified stack slot
0182   void assignVirt2StackSlot(Register virtReg, int SS);
0183 
0184   void print(raw_ostream &OS, const Module *M = nullptr) const;
0185   void dump() const;
0186 };
0187 
0188 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
0189   VRM.print(OS);
0190   return OS;
0191 }
0192 
0193 class VirtRegMapWrapperLegacy : public MachineFunctionPass {
0194   VirtRegMap VRM;
0195 
0196 public:
0197   static char ID;
0198 
0199   VirtRegMapWrapperLegacy() : MachineFunctionPass(ID) {}
0200 
0201   void print(raw_ostream &OS, const Module *M = nullptr) const override {
0202     VRM.print(OS, M);
0203   }
0204 
0205   VirtRegMap &getVRM() { return VRM; }
0206   const VirtRegMap &getVRM() const { return VRM; }
0207 
0208   bool runOnMachineFunction(MachineFunction &MF) override {
0209     VRM.init(MF);
0210     return false;
0211   }
0212 
0213   void getAnalysisUsage(AnalysisUsage &AU) const override {
0214     AU.setPreservesAll();
0215     MachineFunctionPass::getAnalysisUsage(AU);
0216   }
0217 };
0218 
0219 class VirtRegMapAnalysis : public AnalysisInfoMixin<VirtRegMapAnalysis> {
0220   friend AnalysisInfoMixin<VirtRegMapAnalysis>;
0221   static AnalysisKey Key;
0222 
0223 public:
0224   using Result = VirtRegMap;
0225 
0226   VirtRegMap run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM);
0227 };
0228 
0229 class VirtRegMapPrinterPass : public PassInfoMixin<VirtRegMapPrinterPass> {
0230   raw_ostream &OS;
0231 
0232 public:
0233   explicit VirtRegMapPrinterPass(raw_ostream &OS) : OS(OS) {}
0234   PreservedAnalyses run(MachineFunction &MF,
0235                         MachineFunctionAnalysisManager &MFAM);
0236   static bool isRequired() { return true; }
0237 };
0238 } // end llvm namespace
0239 
0240 #endif // LLVM_CODEGEN_VIRTREGMAP_H