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/Pass.h" 24 #include <cassert> 25 26 namespace llvm { 27 28 class MachineFunction; 29 class MachineRegisterInfo; 30 class raw_ostream; 31 class TargetInstrInfo; 32 33 class VirtRegMap : public MachineFunctionPass { 34 public: 35 enum { 36 NO_PHYS_REG = 0, 37 NO_STACK_SLOT = (1L << 30)-1, 38 MAX_STACK_SLOT = (1L << 18)-1 39 }; 40 41 private: 42 MachineRegisterInfo *MRI; 43 const TargetInstrInfo *TII; 44 const TargetRegisterInfo *TRI; 45 MachineFunction *MF; 46 47 /// Virt2PhysMap - This is a virtual to physical register 48 /// mapping. Each virtual register is required to have an entry in 49 /// it; even spilled virtual registers (the register mapped to a 50 /// spilled register is the temporary used to load it from the 51 /// stack). 52 IndexedMap<Register, VirtReg2IndexFunctor> Virt2PhysMap; 53 54 /// Virt2StackSlotMap - This is virtual register to stack slot 55 /// mapping. Each spilled virtual register has an entry in it 56 /// which corresponds to the stack slot this register is spilled 57 /// at. 58 IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; 59 60 /// Virt2SplitMap - This is virtual register to splitted virtual register 61 /// mapping. 62 IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap; 63 64 /// Virt2ShapeMap - For X86 AMX register whose register is bound shape 65 /// information. 66 DenseMap<unsigned, ShapeT> Virt2ShapeMap; 67 68 /// createSpillSlot - Allocate a spill slot for RC from MFI. 69 unsigned createSpillSlot(const TargetRegisterClass *RC); 70 71 public: 72 static char ID; 73 74 VirtRegMap() 75 : MachineFunctionPass(ID), MRI(nullptr), TII(nullptr), TRI(nullptr), 76 MF(nullptr), Virt2PhysMap(NO_PHYS_REG), 77 Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {} 78 VirtRegMap(const VirtRegMap &) = delete; 79 VirtRegMap &operator=(const VirtRegMap &) = delete; 80 81 bool runOnMachineFunction(MachineFunction &MF) override; 82 83 void getAnalysisUsage(AnalysisUsage &AU) const override { 84 AU.setPreservesAll(); 85 MachineFunctionPass::getAnalysisUsage(AU); 86 } 87 88 MachineFunction &getMachineFunction() const { 89 assert(MF && "getMachineFunction called before runOnMachineFunction"); 90 return *MF; 91 } 92 93 MachineRegisterInfo &getRegInfo() const { return *MRI; } 94 const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } 95 96 void grow(); 97 98 /// returns true if the specified virtual register is 99 /// mapped to a physical register 100 bool hasPhys(Register virtReg) const { 101 return getPhys(virtReg) != NO_PHYS_REG; 102 } 103 104 /// returns the physical register mapped to the specified 105 /// virtual register 106 MCRegister getPhys(Register virtReg) const { 107 assert(virtReg.isVirtual()); 108 return MCRegister::from(Virt2PhysMap[virtReg.id()]); 109 } 110 111 /// creates a mapping for the specified virtual register to 112 /// the specified physical register 113 void assignVirt2Phys(Register virtReg, MCPhysReg physReg); 114 115 bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); } 116 117 bool hasShape(Register virtReg) const { 118 return getShape(virtReg).isValid(); 119 } 120 121 ShapeT getShape(Register virtReg) const { 122 assert(virtReg.isVirtual()); 123 return Virt2ShapeMap.lookup(virtReg); 124 } 125 126 void assignVirt2Shape(Register virtReg, ShapeT shape) { 127 Virt2ShapeMap[virtReg.id()] = shape; 128 } 129 130 /// clears the specified virtual register's, physical 131 /// register mapping 132 void clearVirt(Register virtReg) { 133 assert(virtReg.isVirtual()); 134 assert(Virt2PhysMap[virtReg.id()] != NO_PHYS_REG && 135 "attempt to clear a not assigned virtual register"); 136 Virt2PhysMap[virtReg.id()] = NO_PHYS_REG; 137 } 138 139 /// clears all virtual to physical register mappings 140 void clearAllVirt() { 141 Virt2PhysMap.clear(); 142 grow(); 143 } 144 145 /// returns true if VirtReg is assigned to its preferred physreg. 146 bool hasPreferredPhys(Register VirtReg) const; 147 148 /// returns true if VirtReg has a known preferred register. 149 /// This returns false if VirtReg has a preference that is a virtual 150 /// register that hasn't been assigned yet. 151 bool hasKnownPreference(Register VirtReg) const; 152 153 /// records virtReg is a split live interval from SReg. 154 void setIsSplitFromReg(Register virtReg, Register SReg) { 155 Virt2SplitMap[virtReg.id()] = SReg; 156 if (hasShape(SReg)) { 157 Virt2ShapeMap[virtReg.id()] = getShape(SReg); 158 } 159 } 160 161 /// returns the live interval virtReg is split from. 162 Register getPreSplitReg(Register virtReg) const { 163 return Virt2SplitMap[virtReg.id()]; 164 } 165 166 /// getOriginal - Return the original virtual register that VirtReg descends 167 /// from through splitting. 168 /// A register that was not created by splitting is its own original. 169 /// This operation is idempotent. 170 Register getOriginal(Register VirtReg) const { 171 Register Orig = getPreSplitReg(VirtReg); 172 return Orig ? Orig : VirtReg; 173 } 174 175 /// returns true if the specified virtual register is not 176 /// mapped to a stack slot or rematerialized. 177 bool isAssignedReg(Register virtReg) const { 178 if (getStackSlot(virtReg) == NO_STACK_SLOT) 179 return true; 180 // Split register can be assigned a physical register as well as a 181 // stack slot or remat id. 182 return (Virt2SplitMap[virtReg.id()] && 183 Virt2PhysMap[virtReg.id()] != NO_PHYS_REG); 184 } 185 186 /// returns the stack slot mapped to the specified virtual 187 /// register 188 int getStackSlot(Register virtReg) const { 189 assert(virtReg.isVirtual()); 190 return Virt2StackSlotMap[virtReg.id()]; 191 } 192 193 /// create a mapping for the specifed virtual register to 194 /// the next available stack slot 195 int assignVirt2StackSlot(Register virtReg); 196 197 /// create a mapping for the specified virtual register to 198 /// the specified stack slot 199 void assignVirt2StackSlot(Register virtReg, int SS); 200 201 void print(raw_ostream &OS, const Module* M = nullptr) const override; 202 void dump() const; 203 }; 204 205 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { 206 VRM.print(OS); 207 return OS; 208 } 209 210 } // end llvm namespace 211 212 #endif // LLVM_CODEGEN_VIRTREGMAP_H 213