1 //===- llvm/CodeGen/VirtRegMap.h - Virtual Register Map ---------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements a virtual register map. This maps virtual registers to 10 // physical registers and virtual registers to stack slots. It is created and 11 // updated by a register allocator and then used by a machine code rewriter that 12 // adds spill code and rewrites virtual into physical register references. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CODEGEN_VIRTREGMAP_H 17 #define LLVM_CODEGEN_VIRTREGMAP_H 18 19 #include "llvm/ADT/IndexedMap.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/TargetRegisterInfo.h" 22 #include "llvm/CodeGen/TileShapeInfo.h" 23 #include "llvm/IR/PassManager.h" 24 #include "llvm/Pass.h" 25 #include <cassert> 26 27 namespace llvm { 28 29 class MachineFunction; 30 class MachineRegisterInfo; 31 class raw_ostream; 32 class TargetInstrInfo; 33 34 class VirtRegMap { 35 MachineRegisterInfo *MRI = nullptr; 36 const TargetInstrInfo *TII = nullptr; 37 const TargetRegisterInfo *TRI = nullptr; 38 MachineFunction *MF = nullptr; 39 40 /// Virt2PhysMap - This is a virtual to physical register 41 /// mapping. Each virtual register is required to have an entry in 42 /// it; even spilled virtual registers (the register mapped to a 43 /// spilled register is the temporary used to load it from the 44 /// stack). 45 IndexedMap<MCRegister, VirtReg2IndexFunctor> Virt2PhysMap; 46 47 /// Virt2StackSlotMap - This is virtual register to stack slot 48 /// mapping. Each spilled virtual register has an entry in it 49 /// which corresponds to the stack slot this register is spilled 50 /// at. 51 IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; 52 53 /// Virt2SplitMap - This is virtual register to splitted virtual register 54 /// mapping. 55 IndexedMap<Register, VirtReg2IndexFunctor> Virt2SplitMap; 56 57 /// Virt2ShapeMap - For X86 AMX register whose register is bound shape 58 /// information. 59 DenseMap<Register, ShapeT> Virt2ShapeMap; 60 61 /// createSpillSlot - Allocate a spill slot for RC from MFI. 62 unsigned createSpillSlot(const TargetRegisterClass *RC); 63 64 public: 65 static constexpr int NO_STACK_SLOT = INT_MAX; 66 67 VirtRegMap() : Virt2StackSlotMap(NO_STACK_SLOT) {} 68 VirtRegMap(const VirtRegMap &) = delete; 69 VirtRegMap &operator=(const VirtRegMap &) = delete; 70 VirtRegMap(VirtRegMap &&) = default; 71 72 void init(MachineFunction &MF); 73 74 MachineFunction &getMachineFunction() const { 75 assert(MF && "getMachineFunction called before runOnMachineFunction"); 76 return *MF; 77 } 78 79 MachineRegisterInfo &getRegInfo() const { return *MRI; } 80 const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } 81 82 void grow(); 83 84 /// returns true if the specified virtual register is 85 /// mapped to a physical register 86 bool hasPhys(Register virtReg) const { return getPhys(virtReg).isValid(); } 87 88 /// returns the physical register mapped to the specified 89 /// virtual register 90 MCRegister getPhys(Register virtReg) const { 91 assert(virtReg.isVirtual()); 92 return Virt2PhysMap[virtReg]; 93 } 94 95 /// creates a mapping for the specified virtual register to 96 /// the specified physical register 97 void assignVirt2Phys(Register virtReg, MCRegister physReg); 98 99 bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); } 100 101 bool hasShape(Register virtReg) const { 102 return Virt2ShapeMap.contains(virtReg); 103 } 104 105 ShapeT getShape(Register virtReg) const { 106 assert(virtReg.isVirtual()); 107 return Virt2ShapeMap.lookup(virtReg); 108 } 109 110 void assignVirt2Shape(Register virtReg, ShapeT shape) { 111 Virt2ShapeMap[virtReg] = shape; 112 } 113 114 /// clears the specified virtual register's, physical 115 /// register mapping 116 void clearVirt(Register virtReg) { 117 assert(virtReg.isVirtual()); 118 assert(Virt2PhysMap[virtReg] && 119 "attempt to clear a not assigned virtual register"); 120 Virt2PhysMap[virtReg] = MCRegister(); 121 } 122 123 /// clears all virtual to physical register mappings 124 void clearAllVirt() { 125 Virt2PhysMap.clear(); 126 grow(); 127 } 128 129 /// returns true if VirtReg is assigned to its preferred physreg. 130 bool hasPreferredPhys(Register VirtReg) const; 131 132 /// returns true if VirtReg has a known preferred register. 133 /// This returns false if VirtReg has a preference that is a virtual 134 /// register that hasn't been assigned yet. 135 bool hasKnownPreference(Register VirtReg) const; 136 137 /// records virtReg is a split live interval from SReg. 138 void setIsSplitFromReg(Register virtReg, Register SReg) { 139 Virt2SplitMap[virtReg] = SReg; 140 if (hasShape(SReg)) { 141 Virt2ShapeMap[virtReg] = getShape(SReg); 142 } 143 } 144 145 /// returns the live interval virtReg is split from. 146 Register getPreSplitReg(Register virtReg) const { 147 return Virt2SplitMap[virtReg]; 148 } 149 150 /// getOriginal - Return the original virtual register that VirtReg descends 151 /// from through splitting. 152 /// A register that was not created by splitting is its own original. 153 /// This operation is idempotent. 154 Register getOriginal(Register VirtReg) const { 155 Register Orig = getPreSplitReg(VirtReg); 156 return Orig ? Orig : VirtReg; 157 } 158 159 /// returns true if the specified virtual register is not 160 /// mapped to a stack slot or rematerialized. 161 bool isAssignedReg(Register virtReg) const { 162 if (getStackSlot(virtReg) == NO_STACK_SLOT) 163 return true; 164 // Split register can be assigned a physical register as well as a 165 // stack slot or remat id. 166 return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg]); 167 } 168 169 /// returns the stack slot mapped to the specified virtual 170 /// register 171 int getStackSlot(Register virtReg) const { 172 assert(virtReg.isVirtual()); 173 return Virt2StackSlotMap[virtReg]; 174 } 175 176 /// create a mapping for the specifed virtual register to 177 /// the next available stack slot 178 int assignVirt2StackSlot(Register virtReg); 179 180 /// create a mapping for the specified virtual register to 181 /// the specified stack slot 182 void assignVirt2StackSlot(Register virtReg, int SS); 183 184 void print(raw_ostream &OS, const Module *M = nullptr) const; 185 void dump() const; 186 }; 187 188 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { 189 VRM.print(OS); 190 return OS; 191 } 192 193 class VirtRegMapWrapperLegacy : public MachineFunctionPass { 194 VirtRegMap VRM; 195 196 public: 197 static char ID; 198 199 VirtRegMapWrapperLegacy() : MachineFunctionPass(ID) {} 200 201 void print(raw_ostream &OS, const Module *M = nullptr) const override { 202 VRM.print(OS, M); 203 } 204 205 VirtRegMap &getVRM() { return VRM; } 206 const VirtRegMap &getVRM() const { return VRM; } 207 208 bool runOnMachineFunction(MachineFunction &MF) override { 209 VRM.init(MF); 210 return false; 211 } 212 213 void getAnalysisUsage(AnalysisUsage &AU) const override { 214 AU.setPreservesAll(); 215 MachineFunctionPass::getAnalysisUsage(AU); 216 } 217 }; 218 219 class VirtRegMapAnalysis : public AnalysisInfoMixin<VirtRegMapAnalysis> { 220 friend AnalysisInfoMixin<VirtRegMapAnalysis>; 221 static AnalysisKey Key; 222 223 public: 224 using Result = VirtRegMap; 225 226 VirtRegMap run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM); 227 }; 228 229 class VirtRegMapPrinterPass : public PassInfoMixin<VirtRegMapPrinterPass> { 230 raw_ostream &OS; 231 232 public: 233 explicit VirtRegMapPrinterPass(raw_ostream &OS) : OS(OS) {} 234 PreservedAnalyses run(MachineFunction &MF, 235 MachineFunctionAnalysisManager &MFAM); 236 static bool isRequired() { return true; } 237 }; 238 } // end llvm namespace 239 240 #endif // LLVM_CODEGEN_VIRTREGMAP_H 241