File indexing completed on 2026-05-10 08:43:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
0041
0042
0043
0044
0045 IndexedMap<MCRegister, VirtReg2IndexFunctor> Virt2PhysMap;
0046
0047
0048
0049
0050
0051 IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
0052
0053
0054
0055 IndexedMap<Register, VirtReg2IndexFunctor> Virt2SplitMap;
0056
0057
0058
0059 DenseMap<Register, ShapeT> Virt2ShapeMap;
0060
0061
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
0085
0086 bool hasPhys(Register virtReg) const { return getPhys(virtReg).isValid(); }
0087
0088
0089
0090 MCRegister getPhys(Register virtReg) const {
0091 assert(virtReg.isVirtual());
0092 return Virt2PhysMap[virtReg];
0093 }
0094
0095
0096
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
0115
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
0124 void clearAllVirt() {
0125 Virt2PhysMap.clear();
0126 grow();
0127 }
0128
0129
0130 bool hasPreferredPhys(Register VirtReg) const;
0131
0132
0133
0134
0135 bool hasKnownPreference(Register VirtReg) const;
0136
0137
0138 void setIsSplitFromReg(Register virtReg, Register SReg) {
0139 Virt2SplitMap[virtReg] = SReg;
0140 if (hasShape(SReg)) {
0141 Virt2ShapeMap[virtReg] = getShape(SReg);
0142 }
0143 }
0144
0145
0146 Register getPreSplitReg(Register virtReg) const {
0147 return Virt2SplitMap[virtReg];
0148 }
0149
0150
0151
0152
0153
0154 Register getOriginal(Register VirtReg) const {
0155 Register Orig = getPreSplitReg(VirtReg);
0156 return Orig ? Orig : VirtReg;
0157 }
0158
0159
0160
0161 bool isAssignedReg(Register virtReg) const {
0162 if (getStackSlot(virtReg) == NO_STACK_SLOT)
0163 return true;
0164
0165
0166 return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg]);
0167 }
0168
0169
0170
0171 int getStackSlot(Register virtReg) const {
0172 assert(virtReg.isVirtual());
0173 return Virt2StackSlotMap[virtReg];
0174 }
0175
0176
0177
0178 int assignVirt2StackSlot(Register virtReg);
0179
0180
0181
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 }
0239
0240 #endif