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 "llvm/Support/Compiler.h" 26 #include <cassert> 27 28 namespace llvm { 29 30 class MachineFunction; 31 class MachineRegisterInfo; 32 class raw_ostream; 33 class TargetInstrInfo; 34 35 class VirtRegMap { 36 MachineRegisterInfo *MRI = nullptr; 37 const TargetInstrInfo *TII = nullptr; 38 const TargetRegisterInfo *TRI = nullptr; 39 MachineFunction *MF = nullptr; 40 41 /// Virt2PhysMap - This is a virtual to physical register 42 /// mapping. Each virtual register is required to have an entry in 43 /// it; even spilled virtual registers (the register mapped to a 44 /// spilled register is the temporary used to load it from the 45 /// stack). 46 IndexedMap<MCRegister, VirtReg2IndexFunctor> Virt2PhysMap; 47 48 /// Virt2StackSlotMap - This is virtual register to stack slot 49 /// mapping. Each spilled virtual register has an entry in it 50 /// which corresponds to the stack slot this register is spilled 51 /// at. 52 IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; 53 54 /// Virt2SplitMap - This is virtual register to splitted virtual register 55 /// mapping. 56 IndexedMap<Register, VirtReg2IndexFunctor> Virt2SplitMap; 57 58 /// Virt2ShapeMap - For X86 AMX register whose register is bound shape 59 /// information. 60 DenseMap<Register, ShapeT> Virt2ShapeMap; 61 62 /// createSpillSlot - Allocate a spill slot for RC from MFI. 63 unsigned createSpillSlot(const TargetRegisterClass *RC); 64 65 public: 66 static constexpr int NO_STACK_SLOT = INT_MAX; 67 VirtRegMap()68 VirtRegMap() : Virt2StackSlotMap(NO_STACK_SLOT) {} 69 VirtRegMap(const VirtRegMap &) = delete; 70 VirtRegMap &operator=(const VirtRegMap &) = delete; 71 VirtRegMap(VirtRegMap &&) = default; 72 73 LLVM_ABI void init(MachineFunction &MF); 74 getMachineFunction()75 MachineFunction &getMachineFunction() const { 76 assert(MF && "getMachineFunction called before runOnMachineFunction"); 77 return *MF; 78 } 79 getRegInfo()80 MachineRegisterInfo &getRegInfo() const { return *MRI; } getTargetRegInfo()81 const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } 82 83 LLVM_ABI void grow(); 84 85 /// returns true if the specified virtual register is 86 /// mapped to a physical register hasPhys(Register virtReg)87 bool hasPhys(Register virtReg) const { return getPhys(virtReg).isValid(); } 88 89 /// returns the physical register mapped to the specified 90 /// virtual register getPhys(Register virtReg)91 MCRegister getPhys(Register virtReg) const { 92 assert(virtReg.isVirtual()); 93 return Virt2PhysMap[virtReg]; 94 } 95 96 /// creates a mapping for the specified virtual register to 97 /// the specified physical register 98 LLVM_ABI void assignVirt2Phys(Register virtReg, MCRegister physReg); 99 isShapeMapEmpty()100 bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); } 101 hasShape(Register virtReg)102 bool hasShape(Register virtReg) const { 103 return Virt2ShapeMap.contains(virtReg); 104 } 105 getShape(Register virtReg)106 ShapeT getShape(Register virtReg) const { 107 assert(virtReg.isVirtual()); 108 return Virt2ShapeMap.lookup(virtReg); 109 } 110 assignVirt2Shape(Register virtReg,ShapeT shape)111 void assignVirt2Shape(Register virtReg, ShapeT shape) { 112 Virt2ShapeMap[virtReg] = shape; 113 } 114 115 /// clears the specified virtual register's, physical 116 /// register mapping clearVirt(Register virtReg)117 void clearVirt(Register virtReg) { 118 assert(virtReg.isVirtual()); 119 assert(Virt2PhysMap[virtReg] && 120 "attempt to clear a not assigned virtual register"); 121 Virt2PhysMap[virtReg] = MCRegister(); 122 } 123 124 /// clears all virtual to physical register mappings clearAllVirt()125 void clearAllVirt() { 126 Virt2PhysMap.clear(); 127 grow(); 128 } 129 130 /// returns true if VirtReg is assigned to its preferred physreg. 131 LLVM_ABI bool hasPreferredPhys(Register VirtReg) const; 132 133 /// returns true if VirtReg has a known preferred register. 134 /// This returns false if VirtReg has a preference that is a virtual 135 /// register that hasn't been assigned yet. 136 LLVM_ABI bool hasKnownPreference(Register VirtReg) const; 137 138 /// records virtReg is a split live interval from SReg. setIsSplitFromReg(Register virtReg,Register SReg)139 void setIsSplitFromReg(Register virtReg, Register SReg) { 140 Virt2SplitMap[virtReg] = SReg; 141 if (hasShape(SReg)) { 142 Virt2ShapeMap[virtReg] = getShape(SReg); 143 } 144 } 145 146 /// returns the live interval virtReg is split from. getPreSplitReg(Register virtReg)147 Register getPreSplitReg(Register virtReg) const { 148 return Virt2SplitMap[virtReg]; 149 } 150 151 /// getOriginal - Return the original virtual register that VirtReg descends 152 /// from through splitting. 153 /// A register that was not created by splitting is its own original. 154 /// This operation is idempotent. getOriginal(Register VirtReg)155 Register getOriginal(Register VirtReg) const { 156 Register Orig = getPreSplitReg(VirtReg); 157 return Orig ? Orig : VirtReg; 158 } 159 160 /// returns true if the specified virtual register is not 161 /// mapped to a stack slot or rematerialized. isAssignedReg(Register virtReg)162 bool isAssignedReg(Register virtReg) const { 163 if (getStackSlot(virtReg) == NO_STACK_SLOT) 164 return true; 165 // Split register can be assigned a physical register as well as a 166 // stack slot or remat id. 167 return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg]); 168 } 169 170 /// returns the stack slot mapped to the specified virtual 171 /// register getStackSlot(Register virtReg)172 int getStackSlot(Register virtReg) const { 173 assert(virtReg.isVirtual()); 174 return Virt2StackSlotMap[virtReg]; 175 } 176 177 /// create a mapping for the specifed virtual register to 178 /// the next available stack slot 179 LLVM_ABI int assignVirt2StackSlot(Register virtReg); 180 181 /// create a mapping for the specified virtual register to 182 /// the specified stack slot 183 LLVM_ABI void assignVirt2StackSlot(Register virtReg, int SS); 184 185 LLVM_ABI void print(raw_ostream &OS, const Module *M = nullptr) const; 186 LLVM_ABI void dump() const; 187 }; 188 189 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { 190 VRM.print(OS); 191 return OS; 192 } 193 194 class VirtRegMapWrapperLegacy : public MachineFunctionPass { 195 VirtRegMap VRM; 196 197 public: 198 LLVM_ABI static char ID; 199 VirtRegMapWrapperLegacy()200 VirtRegMapWrapperLegacy() : MachineFunctionPass(ID) {} 201 202 void print(raw_ostream &OS, const Module *M = nullptr) const override { 203 VRM.print(OS, M); 204 } 205 getVRM()206 VirtRegMap &getVRM() { return VRM; } getVRM()207 const VirtRegMap &getVRM() const { return VRM; } 208 runOnMachineFunction(MachineFunction & MF)209 bool runOnMachineFunction(MachineFunction &MF) override { 210 VRM.init(MF); 211 return false; 212 } 213 getAnalysisUsage(AnalysisUsage & AU)214 void getAnalysisUsage(AnalysisUsage &AU) const override { 215 AU.setPreservesAll(); 216 MachineFunctionPass::getAnalysisUsage(AU); 217 } 218 }; 219 220 class VirtRegMapAnalysis : public AnalysisInfoMixin<VirtRegMapAnalysis> { 221 friend AnalysisInfoMixin<VirtRegMapAnalysis>; 222 LLVM_ABI static AnalysisKey Key; 223 224 public: 225 using Result = VirtRegMap; 226 227 LLVM_ABI VirtRegMap run(MachineFunction &MF, 228 MachineFunctionAnalysisManager &MAM); 229 }; 230 231 class VirtRegMapPrinterPass : public PassInfoMixin<VirtRegMapPrinterPass> { 232 raw_ostream &OS; 233 234 public: VirtRegMapPrinterPass(raw_ostream & OS)235 explicit VirtRegMapPrinterPass(raw_ostream &OS) : OS(OS) {} 236 LLVM_ABI PreservedAnalyses run(MachineFunction &MF, 237 MachineFunctionAnalysisManager &MFAM); isRequired()238 static bool isRequired() { return true; } 239 }; 240 241 class VirtRegRewriterPass : public PassInfoMixin<VirtRegRewriterPass> { 242 bool ClearVirtRegs = true; 243 244 public: 245 VirtRegRewriterPass(bool ClearVirtRegs = true) ClearVirtRegs(ClearVirtRegs)246 : ClearVirtRegs(ClearVirtRegs) {} 247 LLVM_ABI PreservedAnalyses run(MachineFunction &MF, 248 MachineFunctionAnalysisManager &MFAM); 249 isRequired()250 static bool isRequired() { return true; } 251 252 LLVM_ABI void printPipeline(raw_ostream &OS, 253 function_ref<StringRef(StringRef)>) const; 254 getSetProperties()255 MachineFunctionProperties getSetProperties() const { 256 if (ClearVirtRegs) { 257 return MachineFunctionProperties().set( 258 MachineFunctionProperties::Property::NoVRegs); 259 } 260 return {}; 261 } 262 }; 263 264 } // end llvm namespace 265 266 #endif // LLVM_CODEGEN_VIRTREGMAP_H 267