/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/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 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file implements a virtual register map. This maps virtual registers to |
11 | | // physical registers and virtual registers to stack slots. It is created and |
12 | | // updated by a register allocator and then used by a machine code rewriter that |
13 | | // adds spill code and rewrites virtual into physical register references. |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #ifndef LLVM_CODEGEN_VIRTREGMAP_H |
18 | | #define LLVM_CODEGEN_VIRTREGMAP_H |
19 | | |
20 | | #include "llvm/ADT/IndexedMap.h" |
21 | | #include "llvm/CodeGen/MachineFunctionPass.h" |
22 | | #include "llvm/MC/MCRegisterInfo.h" |
23 | | #include "llvm/Pass.h" |
24 | | #include "llvm/Target/TargetRegisterInfo.h" |
25 | | #include <cassert> |
26 | | |
27 | | namespace llvm { |
28 | | |
29 | | class MachineFunction; |
30 | | class MachineRegisterInfo; |
31 | | class raw_ostream; |
32 | | class TargetInstrInfo; |
33 | | |
34 | | class VirtRegMap : public MachineFunctionPass { |
35 | | public: |
36 | | enum { |
37 | | NO_PHYS_REG = 0, |
38 | | NO_STACK_SLOT = (1L << 30)-1, |
39 | | MAX_STACK_SLOT = (1L << 18)-1 |
40 | | }; |
41 | | |
42 | | private: |
43 | | MachineRegisterInfo *MRI; |
44 | | const TargetInstrInfo *TII; |
45 | | const TargetRegisterInfo *TRI; |
46 | | MachineFunction *MF; |
47 | | |
48 | | /// Virt2PhysMap - This is a virtual to physical register |
49 | | /// mapping. Each virtual register is required to have an entry in |
50 | | /// it; even spilled virtual registers (the register mapped to a |
51 | | /// spilled register is the temporary used to load it from the |
52 | | /// stack). |
53 | | IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap; |
54 | | |
55 | | /// Virt2StackSlotMap - This is virtual register to stack slot |
56 | | /// mapping. Each spilled virtual register has an entry in it |
57 | | /// which corresponds to the stack slot this register is spilled |
58 | | /// at. |
59 | | IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; |
60 | | |
61 | | /// Virt2SplitMap - This is virtual register to splitted virtual register |
62 | | /// mapping. |
63 | | IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap; |
64 | | |
65 | | /// createSpillSlot - Allocate a spill slot for RC from MFI. |
66 | | unsigned createSpillSlot(const TargetRegisterClass *RC); |
67 | | |
68 | | public: |
69 | | static char ID; |
70 | | |
71 | | VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG), |
72 | 31.8k | Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {} |
73 | | VirtRegMap(const VirtRegMap &) = delete; |
74 | | VirtRegMap &operator=(const VirtRegMap &) = delete; |
75 | | |
76 | | bool runOnMachineFunction(MachineFunction &MF) override; |
77 | | |
78 | 31.8k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
79 | 31.8k | AU.setPreservesAll(); |
80 | 31.8k | MachineFunctionPass::getAnalysisUsage(AU); |
81 | 31.8k | } |
82 | | |
83 | 22.3M | MachineFunction &getMachineFunction() const { |
84 | 22.3M | assert(MF && "getMachineFunction called before runOnMachineFunction"); |
85 | 22.3M | return *MF; |
86 | 22.3M | } |
87 | | |
88 | 587k | MachineRegisterInfo &getRegInfo() const { return *MRI; } |
89 | 16.5M | const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } |
90 | | |
91 | | void grow(); |
92 | | |
93 | | /// @brief returns true if the specified virtual register is |
94 | | /// mapped to a physical register |
95 | 3.37M | bool hasPhys(unsigned virtReg) const { |
96 | 3.37M | return getPhys(virtReg) != NO_PHYS_REG; |
97 | 3.37M | } |
98 | | |
99 | | /// @brief returns the physical register mapped to the specified |
100 | | /// virtual register |
101 | 60.8M | unsigned getPhys(unsigned virtReg) const { |
102 | 60.8M | assert(TargetRegisterInfo::isVirtualRegister(virtReg)); |
103 | 60.8M | return Virt2PhysMap[virtReg]; |
104 | 60.8M | } |
105 | | |
106 | | /// @brief creates a mapping for the specified virtual register to |
107 | | /// the specified physical register |
108 | | void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg); |
109 | | |
110 | | /// @brief clears the specified virtual register's, physical |
111 | | /// register mapping |
112 | 603k | void clearVirt(unsigned virtReg) { |
113 | 603k | assert(TargetRegisterInfo::isVirtualRegister(virtReg)); |
114 | 603k | assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && |
115 | 603k | "attempt to clear a not assigned virtual register"); |
116 | 603k | Virt2PhysMap[virtReg] = NO_PHYS_REG; |
117 | 603k | } |
118 | | |
119 | | /// @brief clears all virtual to physical register mappings |
120 | 587k | void clearAllVirt() { |
121 | 587k | Virt2PhysMap.clear(); |
122 | 587k | grow(); |
123 | 587k | } |
124 | | |
125 | | /// @brief returns true if VirtReg is assigned to its preferred physreg. |
126 | | bool hasPreferredPhys(unsigned VirtReg); |
127 | | |
128 | | /// @brief returns true if VirtReg has a known preferred register. |
129 | | /// This returns false if VirtReg has a preference that is a virtual |
130 | | /// register that hasn't been assigned yet. |
131 | | bool hasKnownPreference(unsigned VirtReg); |
132 | | |
133 | | /// @brief records virtReg is a split live interval from SReg. |
134 | 771k | void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { |
135 | 771k | Virt2SplitMap[virtReg] = SReg; |
136 | 771k | } |
137 | | |
138 | | /// @brief returns the live interval virtReg is split from. |
139 | 31.8M | unsigned getPreSplitReg(unsigned virtReg) const { |
140 | 31.8M | return Virt2SplitMap[virtReg]; |
141 | 31.8M | } |
142 | | |
143 | | /// getOriginal - Return the original virtual register that VirtReg descends |
144 | | /// from through splitting. |
145 | | /// A register that was not created by splitting is its own original. |
146 | | /// This operation is idempotent. |
147 | 10.4M | unsigned getOriginal(unsigned VirtReg) const { |
148 | 10.4M | unsigned Orig = getPreSplitReg(VirtReg); |
149 | 10.4M | return Orig ? Orig2.20M : VirtReg8.20M ; |
150 | 10.4M | } |
151 | | |
152 | | /// @brief returns true if the specified virtual register is not |
153 | | /// mapped to a stack slot or rematerialized. |
154 | 325 | bool isAssignedReg(unsigned virtReg) const { |
155 | 325 | if (getStackSlot(virtReg) == NO_STACK_SLOT) |
156 | 315 | return true; |
157 | 325 | // Split register can be assigned a physical register as well as a |
158 | 325 | // stack slot or remat id. |
159 | 10 | return (Virt2SplitMap[virtReg] && 10 Virt2PhysMap[virtReg] != NO_PHYS_REG5 ); |
160 | 325 | } |
161 | | |
162 | | /// @brief returns the stack slot mapped to the specified virtual |
163 | | /// register |
164 | 282k | int getStackSlot(unsigned virtReg) const { |
165 | 282k | assert(TargetRegisterInfo::isVirtualRegister(virtReg)); |
166 | 282k | return Virt2StackSlotMap[virtReg]; |
167 | 282k | } |
168 | | |
169 | | /// @brief create a mapping for the specifed virtual register to |
170 | | /// the next available stack slot |
171 | | int assignVirt2StackSlot(unsigned virtReg); |
172 | | |
173 | | /// @brief create a mapping for the specified virtual register to |
174 | | /// the specified stack slot |
175 | | void assignVirt2StackSlot(unsigned virtReg, int frameIndex); |
176 | | |
177 | | void print(raw_ostream &OS, const Module* M = nullptr) const override; |
178 | | void dump() const; |
179 | | }; |
180 | | |
181 | 0 | inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { |
182 | 0 | VRM.print(OS); |
183 | 0 | return OS; |
184 | 0 | } |
185 | | |
186 | | } // end llvm namespace |
187 | | |
188 | | #endif // LLVM_CODEGEN_VIRTREGMAP_H |