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 | |
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 | |
82 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
83 | AU.setPreservesAll(); |
84 | MachineFunctionPass::getAnalysisUsage(AU); |
85 | } |
86 | |
87 | MachineFunction &getMachineFunction() const { |
88 | assert(MF && "getMachineFunction called before runOnMachineFunction" ); |
89 | return *MF; |
90 | } |
91 | |
92 | MachineRegisterInfo &getRegInfo() const { return *MRI; } |
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 |
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 |
105 | MCRegister getPhys(Register virtReg) const { |
106 | assert(virtReg.isVirtual()); |
107 | return MCRegister::from(Val: 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 | |
114 | bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); } |
115 | |
116 | bool hasShape(Register virtReg) const { |
117 | return getShape(virtReg).isValid(); |
118 | } |
119 | |
120 | ShapeT getShape(Register virtReg) const { |
121 | assert(virtReg.isVirtual()); |
122 | return Virt2ShapeMap.lookup(Val: virtReg); |
123 | } |
124 | |
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 |
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 |
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. |
153 | void setIsSplitFromReg(Register virtReg, Register SReg) { |
154 | Virt2SplitMap[virtReg.id()] = SReg; |
155 | if (hasShape(virtReg: SReg)) { |
156 | Virt2ShapeMap[virtReg.id()] = getShape(virtReg: SReg); |
157 | } |
158 | } |
159 | |
160 | /// returns the live interval virtReg is split from. |
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. |
169 | Register getOriginal(Register VirtReg) const { |
170 | Register Orig = getPreSplitReg(virtReg: 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. |
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 |
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 | |