/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/ExpandPostRAPseudos.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===// |
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 defines a pass that expands COPY and SUBREG_TO_REG pseudo |
10 | | // instructions after register allocation. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/CodeGen/MachineFunctionPass.h" |
15 | | #include "llvm/CodeGen/MachineInstr.h" |
16 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
17 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
18 | | #include "llvm/CodeGen/Passes.h" |
19 | | #include "llvm/CodeGen/TargetInstrInfo.h" |
20 | | #include "llvm/CodeGen/TargetRegisterInfo.h" |
21 | | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
22 | | #include "llvm/Support/Debug.h" |
23 | | #include "llvm/Support/raw_ostream.h" |
24 | | |
25 | | using namespace llvm; |
26 | | |
27 | | #define DEBUG_TYPE "postrapseudos" |
28 | | |
29 | | namespace { |
30 | | struct ExpandPostRA : public MachineFunctionPass { |
31 | | private: |
32 | | const TargetRegisterInfo *TRI; |
33 | | const TargetInstrInfo *TII; |
34 | | |
35 | | public: |
36 | | static char ID; // Pass identification, replacement for typeid |
37 | 36.3k | ExpandPostRA() : MachineFunctionPass(ID) {} |
38 | | |
39 | 36.0k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
40 | 36.0k | AU.setPreservesCFG(); |
41 | 36.0k | AU.addPreservedID(MachineLoopInfoID); |
42 | 36.0k | AU.addPreservedID(MachineDominatorsID); |
43 | 36.0k | MachineFunctionPass::getAnalysisUsage(AU); |
44 | 36.0k | } |
45 | | |
46 | | /// runOnMachineFunction - pass entry point |
47 | | bool runOnMachineFunction(MachineFunction&) override; |
48 | | |
49 | | private: |
50 | | bool LowerSubregToReg(MachineInstr *MI); |
51 | | bool LowerCopy(MachineInstr *MI); |
52 | | |
53 | | void TransferImplicitOperands(MachineInstr *MI); |
54 | | }; |
55 | | } // end anonymous namespace |
56 | | |
57 | | char ExpandPostRA::ID = 0; |
58 | | char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID; |
59 | | |
60 | | INITIALIZE_PASS(ExpandPostRA, DEBUG_TYPE, |
61 | | "Post-RA pseudo instruction expansion pass", false, false) |
62 | | |
63 | | /// TransferImplicitOperands - MI is a pseudo-instruction, and the lowered |
64 | | /// replacement instructions immediately precede it. Copy any implicit |
65 | | /// operands from MI to the replacement instruction. |
66 | 139k | void ExpandPostRA::TransferImplicitOperands(MachineInstr *MI) { |
67 | 139k | MachineBasicBlock::iterator CopyMI = MI; |
68 | 139k | --CopyMI; |
69 | 139k | |
70 | 139k | for (const MachineOperand &MO : MI->implicit_operands()) |
71 | 141k | if (MO.isReg()) |
72 | 141k | CopyMI->addOperand(MO); |
73 | 139k | } |
74 | | |
75 | 185 | bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { |
76 | 185 | MachineBasicBlock *MBB = MI->getParent(); |
77 | 185 | assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && |
78 | 185 | MI->getOperand(1).isImm() && |
79 | 185 | (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && |
80 | 185 | MI->getOperand(3).isImm() && "Invalid subreg_to_reg"); |
81 | 185 | |
82 | 185 | unsigned DstReg = MI->getOperand(0).getReg(); |
83 | 185 | unsigned InsReg = MI->getOperand(2).getReg(); |
84 | 185 | assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); |
85 | 185 | unsigned SubIdx = MI->getOperand(3).getImm(); |
86 | 185 | |
87 | 185 | assert(SubIdx != 0 && "Invalid index for insert_subreg"); |
88 | 185 | unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx); |
89 | 185 | |
90 | 185 | assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && |
91 | 185 | "Insert destination must be in a physical register"); |
92 | 185 | assert(TargetRegisterInfo::isPhysicalRegister(InsReg) && |
93 | 185 | "Inserted value must be in a physical register"); |
94 | 185 | |
95 | 185 | LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); |
96 | 185 | |
97 | 185 | if (MI->allDefsAreDead()) { |
98 | 1 | MI->setDesc(TII->get(TargetOpcode::KILL)); |
99 | 1 | MI->RemoveOperand(3); // SubIdx |
100 | 1 | MI->RemoveOperand(1); // Imm |
101 | 1 | LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI); |
102 | 1 | return true; |
103 | 1 | } |
104 | 184 | |
105 | 184 | if (DstSubReg == InsReg) { |
106 | 10 | // No need to insert an identity copy instruction. |
107 | 10 | // Watch out for case like this: |
108 | 10 | // %rax = SUBREG_TO_REG 0, killed %eax, 3 |
109 | 10 | // We must leave %rax live. |
110 | 10 | if (DstReg != InsReg) { |
111 | 10 | MI->setDesc(TII->get(TargetOpcode::KILL)); |
112 | 10 | MI->RemoveOperand(3); // SubIdx |
113 | 10 | MI->RemoveOperand(1); // Imm |
114 | 10 | LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI); |
115 | 10 | return true; |
116 | 10 | } |
117 | 0 | LLVM_DEBUG(dbgs() << "subreg: eliminated!"); |
118 | 174 | } else { |
119 | 174 | TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, |
120 | 174 | MI->getOperand(2).isKill()); |
121 | 174 | |
122 | 174 | // Implicitly define DstReg for subsequent uses. |
123 | 174 | MachineBasicBlock::iterator CopyMI = MI; |
124 | 174 | --CopyMI; |
125 | 174 | CopyMI->addRegisterDefined(DstReg); |
126 | 174 | LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI); |
127 | 174 | } |
128 | 184 | |
129 | 184 | LLVM_DEBUG174 (dbgs() << '\n'); |
130 | 174 | MBB->erase(MI); |
131 | 174 | return true; |
132 | 184 | } |
133 | | |
134 | 2.37M | bool ExpandPostRA::LowerCopy(MachineInstr *MI) { |
135 | 2.37M | |
136 | 2.37M | if (MI->allDefsAreDead()) { |
137 | 118 | LLVM_DEBUG(dbgs() << "dead copy: " << *MI); |
138 | 118 | MI->setDesc(TII->get(TargetOpcode::KILL)); |
139 | 118 | LLVM_DEBUG(dbgs() << "replaced by: " << *MI); |
140 | 118 | return true; |
141 | 118 | } |
142 | 2.37M | |
143 | 2.37M | MachineOperand &DstMO = MI->getOperand(0); |
144 | 2.37M | MachineOperand &SrcMO = MI->getOperand(1); |
145 | 2.37M | |
146 | 2.37M | bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg()); |
147 | 2.37M | if (IdentityCopy || SrcMO.isUndef()2.37M ) { |
148 | 1.40k | LLVM_DEBUG(dbgs() << (IdentityCopy ? "identity copy: " : "undef copy: ") |
149 | 1.40k | << *MI); |
150 | 1.40k | // No need to insert an identity copy instruction, but replace with a KILL |
151 | 1.40k | // if liveness is changed. |
152 | 1.40k | if (SrcMO.isUndef() || MI->getNumOperands() > 21.40k ) { |
153 | 1.00k | // We must make sure the super-register gets killed. Replace the |
154 | 1.00k | // instruction with KILL. |
155 | 1.00k | MI->setDesc(TII->get(TargetOpcode::KILL)); |
156 | 1.00k | LLVM_DEBUG(dbgs() << "replaced by: " << *MI); |
157 | 1.00k | return true; |
158 | 1.00k | } |
159 | 403 | // Vanilla identity copy. |
160 | 403 | MI->eraseFromParent(); |
161 | 403 | return true; |
162 | 403 | } |
163 | 2.37M | |
164 | 2.37M | LLVM_DEBUG(dbgs() << "real copy: " << *MI); |
165 | 2.37M | TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(), |
166 | 2.37M | DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill()); |
167 | 2.37M | |
168 | 2.37M | if (MI->getNumOperands() > 2) |
169 | 139k | TransferImplicitOperands(MI); |
170 | 2.37M | LLVM_DEBUG({ |
171 | 2.37M | MachineBasicBlock::iterator dMI = MI; |
172 | 2.37M | dbgs() << "replaced by: " << *(--dMI); |
173 | 2.37M | }); |
174 | 2.37M | MI->eraseFromParent(); |
175 | 2.37M | return true; |
176 | 2.37M | } |
177 | | |
178 | | /// runOnMachineFunction - Reduce subregister inserts and extracts to register |
179 | | /// copies. |
180 | | /// |
181 | 498k | bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) { |
182 | 498k | LLVM_DEBUG(dbgs() << "Machine Function\n" |
183 | 498k | << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" |
184 | 498k | << "********** Function: " << MF.getName() << '\n'); |
185 | 498k | TRI = MF.getSubtarget().getRegisterInfo(); |
186 | 498k | TII = MF.getSubtarget().getInstrInfo(); |
187 | 498k | |
188 | 498k | bool MadeChange = false; |
189 | 498k | |
190 | 498k | for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); |
191 | 3.20M | mbbi != mbbe; ++mbbi2.70M ) { |
192 | 2.70M | for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); |
193 | 21.0M | mi != me;) { |
194 | 18.3M | MachineInstr &MI = *mi; |
195 | 18.3M | // Advance iterator here because MI may be erased. |
196 | 18.3M | ++mi; |
197 | 18.3M | |
198 | 18.3M | // Only expand pseudos. |
199 | 18.3M | if (!MI.isPseudo()) |
200 | 14.8M | continue; |
201 | 3.47M | |
202 | 3.47M | // Give targets a chance to expand even standard pseudos. |
203 | 3.47M | if (TII->expandPostRAPseudo(MI)) { |
204 | 114k | MadeChange = true; |
205 | 114k | continue; |
206 | 114k | } |
207 | 3.36M | |
208 | 3.36M | // Expand standard pseudos. |
209 | 3.36M | switch (MI.getOpcode()) { |
210 | 3.36M | case TargetOpcode::SUBREG_TO_REG: |
211 | 185 | MadeChange |= LowerSubregToReg(&MI); |
212 | 185 | break; |
213 | 3.36M | case TargetOpcode::COPY: |
214 | 2.37M | MadeChange |= LowerCopy(&MI); |
215 | 2.37M | break; |
216 | 3.36M | case TargetOpcode::DBG_VALUE: |
217 | 5.21k | continue; |
218 | 3.36M | case TargetOpcode::INSERT_SUBREG: |
219 | 0 | case TargetOpcode::EXTRACT_SUBREG: |
220 | 0 | llvm_unreachable("Sub-register pseudos should have been eliminated."); |
221 | 3.36M | } |
222 | 3.36M | } |
223 | 2.70M | } |
224 | 498k | |
225 | 498k | return MadeChange; |
226 | 498k | } |