/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/VirtRegMap.h
Line | Count | Source (jump to first uncovered line) |
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<unsigned, 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 | | |
70 | | VirtRegMap() |
71 | | : MachineFunctionPass(ID), MRI(nullptr), TII(nullptr), TRI(nullptr), |
72 | | MF(nullptr), Virt2PhysMap(NO_PHYS_REG), |
73 | 36.0k | 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 | | |
79 | 35.9k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
80 | 35.9k | AU.setPreservesAll(); |
81 | 35.9k | MachineFunctionPass::getAnalysisUsage(AU); |
82 | 35.9k | } |
83 | | |
84 | 17.8M | MachineFunction &getMachineFunction() const { |
85 | 17.8M | assert(MF && "getMachineFunction called before runOnMachineFunction"); |
86 | 17.8M | return *MF; |
87 | 17.8M | } |
88 | | |
89 | 484k | MachineRegisterInfo &getRegInfo() const { return *MRI; } |
90 | 12.6M | 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 |
96 | 3.12M | bool hasPhys(unsigned virtReg) const { |
97 | 3.12M | return getPhys(virtReg) != NO_PHYS_REG; |
98 | 3.12M | } |
99 | | |
100 | | /// returns the physical register mapped to the specified |
101 | | /// virtual register |
102 | 46.1M | Register getPhys(Register virtReg) const { |
103 | 46.1M | assert(virtReg.isVirtual()); |
104 | 46.1M | return Virt2PhysMap[virtReg]; |
105 | 46.1M | } |
106 | | |
107 | | /// creates a mapping for the specified virtual register to |
108 | | /// the specified physical register |
109 | | void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg); |
110 | | |
111 | | /// clears the specified virtual register's, physical |
112 | | /// register mapping |
113 | 574k | void clearVirt(unsigned virtReg) { |
114 | 574k | assert(TargetRegisterInfo::isVirtualRegister(virtReg)); |
115 | 574k | assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && |
116 | 574k | "attempt to clear a not assigned virtual register"); |
117 | 574k | Virt2PhysMap[virtReg] = NO_PHYS_REG; |
118 | 574k | } |
119 | | |
120 | | /// clears all virtual to physical register mappings |
121 | 484k | void clearAllVirt() { |
122 | 484k | Virt2PhysMap.clear(); |
123 | 484k | grow(); |
124 | 484k | } |
125 | | |
126 | | /// returns true if VirtReg is assigned to its preferred physreg. |
127 | | bool hasPreferredPhys(unsigned 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(unsigned VirtReg); |
133 | | |
134 | | /// records virtReg is a split live interval from SReg. |
135 | 960k | void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { |
136 | 960k | Virt2SplitMap[virtReg] = SReg; |
137 | 960k | } |
138 | | |
139 | | /// returns the live interval virtReg is split from. |
140 | 28.2M | unsigned getPreSplitReg(unsigned virtReg) const { |
141 | 28.2M | return Virt2SplitMap[virtReg]; |
142 | 28.2M | } |
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. |
148 | 9.60M | unsigned getOriginal(unsigned VirtReg) const { |
149 | 9.60M | unsigned Orig = getPreSplitReg(VirtReg); |
150 | 9.60M | return Orig ? Orig2.79M : VirtReg6.80M ; |
151 | 9.60M | } |
152 | | |
153 | | /// returns true if the specified virtual register is not |
154 | | /// mapped to a stack slot or rematerialized. |
155 | 30.9k | bool isAssignedReg(unsigned virtReg) const { |
156 | 30.9k | if (getStackSlot(virtReg) == NO_STACK_SLOT) |
157 | 30.9k | return true; |
158 | 16 | // Split register can be assigned a physical register as well as a |
159 | 16 | // stack slot or remat id. |
160 | 16 | return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG10 ); |
161 | 16 | } |
162 | | |
163 | | /// returns the stack slot mapped to the specified virtual |
164 | | /// register |
165 | 310k | int getStackSlot(unsigned virtReg) const { |
166 | 310k | assert(TargetRegisterInfo::isVirtualRegister(virtReg)); |
167 | 310k | return Virt2StackSlotMap[virtReg]; |
168 | 310k | } |
169 | | |
170 | | /// create a mapping for the specifed virtual register to |
171 | | /// the next available stack slot |
172 | | int assignVirt2StackSlot(unsigned virtReg); |
173 | | |
174 | | /// create a mapping for the specified virtual register to |
175 | | /// the specified stack slot |
176 | | void assignVirt2StackSlot(unsigned virtReg, int SS); |
177 | | |
178 | | void print(raw_ostream &OS, const Module* M = nullptr) const override; |
179 | | void dump() const; |
180 | | }; |
181 | | |
182 | 0 | inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { |
183 | 0 | VRM.print(OS); |
184 | 0 | return OS; |
185 | 0 | } |
186 | | |
187 | | } // end llvm namespace |
188 | | |
189 | | #endif // LLVM_CODEGEN_VIRTREGMAP_H |