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 = nullptr; 43 const TargetInstrInfo *TII = nullptr; 44 const TargetRegisterInfo *TRI = nullptr; 45 MachineFunction *MF = nullptr; 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 VirtRegMap()74 VirtRegMap() 75 : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG), 76 Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {} 77 VirtRegMap(const VirtRegMap &) = delete; 78 VirtRegMap &operator=(const VirtRegMap &) = delete; 79 80 bool runOnMachineFunction(MachineFunction &MF) override; 81 getAnalysisUsage(AnalysisUsage & AU)82 void getAnalysisUsage(AnalysisUsage &AU) const override { 83 AU.setPreservesAll(); 84 MachineFunctionPass::getAnalysisUsage(AU); 85 } 86 getMachineFunction()87 MachineFunction &getMachineFunction() const { 88 assert(MF && "getMachineFunction called before runOnMachineFunction"); 89 return *MF; 90 } 91 getRegInfo()92 MachineRegisterInfo &getRegInfo() const { return *MRI; } getTargetRegInfo()93 const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } 94 95 void grow(); 96 97 /// returns true if the specified virtual register is 98 /// mapped to a physical register hasPhys(Register virtReg)99 bool hasPhys(Register virtReg) const { 100 return getPhys(virtReg) != NO_PHYS_REG; 101 } 102 103 /// returns the physical register mapped to the specified 104 /// virtual register getPhys(Register virtReg)105 MCRegister getPhys(Register virtReg) const { 106 assert(virtReg.isVirtual()); 107 return MCRegister::from(Virt2PhysMap[virtReg.id()]); 108 } 109 110 /// creates a mapping for the specified virtual register to 111 /// the specified physical register 112 void assignVirt2Phys(Register virtReg, MCPhysReg physReg); 113 isShapeMapEmpty()114 bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); } 115 hasShape(Register virtReg)116 bool hasShape(Register virtReg) const { 117 return getShape(virtReg).isValid(); 118 } 119 getShape(Register virtReg)120 ShapeT getShape(Register virtReg) const { 121 assert(virtReg.isVirtual()); 122 return Virt2ShapeMap.lookup(virtReg); 123 } 124 assignVirt2Shape(Register virtReg,ShapeT shape)125 void assignVirt2Shape(Register virtReg, ShapeT shape) { 126 Virt2ShapeMap[virtReg.id()] = shape; 127 } 128 129 /// clears the specified virtual register's, physical 130 /// register mapping clearVirt(Register virtReg)131 void clearVirt(Register virtReg) { 132 assert(virtReg.isVirtual()); 133 assert(Virt2PhysMap[virtReg.id()] != NO_PHYS_REG && 134 "attempt to clear a not assigned virtual register"); 135 Virt2PhysMap[virtReg.id()] = NO_PHYS_REG; 136 } 137 138 /// clears all virtual to physical register mappings clearAllVirt()139 void clearAllVirt() { 140 Virt2PhysMap.clear(); 141 grow(); 142 } 143 144 /// returns true if VirtReg is assigned to its preferred physreg. 145 bool hasPreferredPhys(Register VirtReg) const; 146 147 /// returns true if VirtReg has a known preferred register. 148 /// This returns false if VirtReg has a preference that is a virtual 149 /// register that hasn't been assigned yet. 150 bool hasKnownPreference(Register VirtReg) const; 151 152 /// records virtReg is a split live interval from SReg. setIsSplitFromReg(Register virtReg,Register SReg)153 void setIsSplitFromReg(Register virtReg, Register SReg) { 154 Virt2SplitMap[virtReg.id()] = SReg; 155 if (hasShape(SReg)) { 156 Virt2ShapeMap[virtReg.id()] = getShape(SReg); 157 } 158 } 159 160 /// returns the live interval virtReg is split from. getPreSplitReg(Register virtReg)161 Register getPreSplitReg(Register virtReg) const { 162 return Virt2SplitMap[virtReg.id()]; 163 } 164 165 /// getOriginal - Return the original virtual register that VirtReg descends 166 /// from through splitting. 167 /// A register that was not created by splitting is its own original. 168 /// This operation is idempotent. getOriginal(Register VirtReg)169 Register getOriginal(Register VirtReg) const { 170 Register Orig = getPreSplitReg(VirtReg); 171 return Orig ? Orig : VirtReg; 172 } 173 174 /// returns true if the specified virtual register is not 175 /// mapped to a stack slot or rematerialized. isAssignedReg(Register virtReg)176 bool isAssignedReg(Register virtReg) const { 177 if (getStackSlot(virtReg) == NO_STACK_SLOT) 178 return true; 179 // Split register can be assigned a physical register as well as a 180 // stack slot or remat id. 181 return (Virt2SplitMap[virtReg.id()] && 182 Virt2PhysMap[virtReg.id()] != NO_PHYS_REG); 183 } 184 185 /// returns the stack slot mapped to the specified virtual 186 /// register getStackSlot(Register virtReg)187 int getStackSlot(Register virtReg) const { 188 assert(virtReg.isVirtual()); 189 return Virt2StackSlotMap[virtReg.id()]; 190 } 191 192 /// create a mapping for the specifed virtual register to 193 /// the next available stack slot 194 int assignVirt2StackSlot(Register virtReg); 195 196 /// create a mapping for the specified virtual register to 197 /// the specified stack slot 198 void assignVirt2StackSlot(Register virtReg, int SS); 199 200 void print(raw_ostream &OS, const Module* M = nullptr) const override; 201 void dump() const; 202 }; 203 204 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { 205 VRM.print(OS); 206 return OS; 207 } 208 209 } // end llvm namespace 210 211 #endif // LLVM_CODEGEN_VIRTREGMAP_H 212