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