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