/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/MachineInstrBundle.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===// |
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 | | #include "llvm/CodeGen/MachineInstrBundle.h" |
11 | | #include "llvm/ADT/SmallSet.h" |
12 | | #include "llvm/ADT/SmallVector.h" |
13 | | #include "llvm/CodeGen/MachineFunctionPass.h" |
14 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
15 | | #include "llvm/CodeGen/Passes.h" |
16 | | #include "llvm/Target/TargetInstrInfo.h" |
17 | | #include "llvm/Target/TargetMachine.h" |
18 | | #include "llvm/Target/TargetRegisterInfo.h" |
19 | | #include "llvm/Target/TargetSubtargetInfo.h" |
20 | | #include <utility> |
21 | | using namespace llvm; |
22 | | |
23 | | namespace { |
24 | | class UnpackMachineBundles : public MachineFunctionPass { |
25 | | public: |
26 | | static char ID; // Pass identification |
27 | | UnpackMachineBundles( |
28 | | std::function<bool(const MachineFunction &)> Ftor = nullptr) |
29 | 4.38k | : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) { |
30 | 4.38k | initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry()); |
31 | 4.38k | } |
32 | | |
33 | | bool runOnMachineFunction(MachineFunction &MF) override; |
34 | | |
35 | | private: |
36 | | std::function<bool(const MachineFunction &)> PredicateFtor; |
37 | | }; |
38 | | } // end anonymous namespace |
39 | | |
40 | | char UnpackMachineBundles::ID = 0; |
41 | | char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID; |
42 | | INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles", |
43 | | "Unpack machine instruction bundles", false, false) |
44 | | |
45 | 17.0k | bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { |
46 | 17.0k | if (PredicateFtor && 17.0k !PredicateFtor(MF)17.0k ) |
47 | 8.37k | return false; |
48 | 8.63k | |
49 | 8.63k | bool Changed = false; |
50 | 50.4k | for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E50.4k ; ++I41.8k ) { |
51 | 41.8k | MachineBasicBlock *MBB = &*I; |
52 | 41.8k | |
53 | 41.8k | for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(), |
54 | 341k | MIE = MBB->instr_end(); MII != MIE341k ; ) { |
55 | 299k | MachineInstr *MI = &*MII; |
56 | 299k | |
57 | 299k | // Remove BUNDLE instruction and the InsideBundle flags from bundled |
58 | 299k | // instructions. |
59 | 299k | if (MI->isBundle()299k ) { |
60 | 23.0k | while (++MII != MIE && 23.0k MII->isBundledWithPred()22.6k ) { |
61 | 16.2k | MII->unbundleFromPred(); |
62 | 99.4k | for (unsigned i = 0, e = MII->getNumOperands(); i != e99.4k ; ++i83.2k ) { |
63 | 83.2k | MachineOperand &MO = MII->getOperand(i); |
64 | 83.2k | if (MO.isReg() && 83.2k MO.isInternalRead()54.6k ) |
65 | 12.0k | MO.setIsInternalRead(false); |
66 | 83.2k | } |
67 | 16.2k | } |
68 | 6.80k | MI->eraseFromParent(); |
69 | 6.80k | |
70 | 6.80k | Changed = true; |
71 | 6.80k | continue; |
72 | 6.80k | } |
73 | 292k | |
74 | 292k | ++MII; |
75 | 292k | } |
76 | 41.8k | } |
77 | 17.0k | |
78 | 17.0k | return Changed; |
79 | 17.0k | } |
80 | | |
81 | | FunctionPass * |
82 | | llvm::createUnpackMachineBundles( |
83 | 4.38k | std::function<bool(const MachineFunction &)> Ftor) { |
84 | 4.38k | return new UnpackMachineBundles(std::move(Ftor)); |
85 | 4.38k | } |
86 | | |
87 | | namespace { |
88 | | class FinalizeMachineBundles : public MachineFunctionPass { |
89 | | public: |
90 | | static char ID; // Pass identification |
91 | 244 | FinalizeMachineBundles() : MachineFunctionPass(ID) { |
92 | 244 | initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry()); |
93 | 244 | } |
94 | | |
95 | | bool runOnMachineFunction(MachineFunction &MF) override; |
96 | | }; |
97 | | } // end anonymous namespace |
98 | | |
99 | | char FinalizeMachineBundles::ID = 0; |
100 | | char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID; |
101 | | INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles", |
102 | | "Finalize machine instruction bundles", false, false) |
103 | | |
104 | 2.05k | bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) { |
105 | 2.05k | return llvm::finalizeBundles(MF); |
106 | 2.05k | } |
107 | | |
108 | | |
109 | | /// finalizeBundle - Finalize a machine instruction bundle which includes |
110 | | /// a sequence of instructions starting from FirstMI to LastMI (exclusive). |
111 | | /// This routine adds a BUNDLE instruction to represent the bundle, it adds |
112 | | /// IsInternalRead markers to MachineOperands which are defined inside the |
113 | | /// bundle, and it copies externally visible defs and uses to the BUNDLE |
114 | | /// instruction. |
115 | | void llvm::finalizeBundle(MachineBasicBlock &MBB, |
116 | | MachineBasicBlock::instr_iterator FirstMI, |
117 | 24.2k | MachineBasicBlock::instr_iterator LastMI) { |
118 | 24.2k | assert(FirstMI != LastMI && "Empty bundle?"); |
119 | 24.2k | MIBundleBuilder Bundle(MBB, FirstMI, LastMI); |
120 | 24.2k | |
121 | 24.2k | MachineFunction &MF = *MBB.getParent(); |
122 | 24.2k | const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); |
123 | 24.2k | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
124 | 24.2k | |
125 | 24.2k | MachineInstrBuilder MIB = |
126 | 24.2k | BuildMI(MF, FirstMI->getDebugLoc(), TII->get(TargetOpcode::BUNDLE)); |
127 | 24.2k | Bundle.prepend(MIB); |
128 | 24.2k | |
129 | 24.2k | SmallVector<unsigned, 32> LocalDefs; |
130 | 24.2k | SmallSet<unsigned, 32> LocalDefSet; |
131 | 24.2k | SmallSet<unsigned, 8> DeadDefSet; |
132 | 24.2k | SmallSet<unsigned, 16> KilledDefSet; |
133 | 24.2k | SmallVector<unsigned, 8> ExternUses; |
134 | 24.2k | SmallSet<unsigned, 8> ExternUseSet; |
135 | 24.2k | SmallSet<unsigned, 8> KilledUseSet; |
136 | 24.2k | SmallSet<unsigned, 8> UndefUseSet; |
137 | 24.2k | SmallVector<MachineOperand*, 4> Defs; |
138 | 87.4k | for (; FirstMI != LastMI87.4k ; ++FirstMI63.1k ) { |
139 | 889k | for (unsigned i = 0, e = FirstMI->getNumOperands(); i != e889k ; ++i826k ) { |
140 | 826k | MachineOperand &MO = FirstMI->getOperand(i); |
141 | 826k | if (!MO.isReg()) |
142 | 597k | continue; |
143 | 228k | if (228k MO.isDef()228k ) { |
144 | 64.6k | Defs.push_back(&MO); |
145 | 64.6k | continue; |
146 | 64.6k | } |
147 | 163k | |
148 | 163k | unsigned Reg = MO.getReg(); |
149 | 163k | if (!Reg) |
150 | 5.37k | continue; |
151 | 163k | assert(TargetRegisterInfo::isPhysicalRegister(Reg)); |
152 | 158k | if (LocalDefSet.count(Reg)158k ) { |
153 | 15.7k | MO.setIsInternalRead(); |
154 | 15.7k | if (MO.isKill()) |
155 | 15.7k | // Internal def is now killed. |
156 | 10.3k | KilledDefSet.insert(Reg); |
157 | 158k | } else { |
158 | 142k | if (ExternUseSet.insert(Reg).second142k ) { |
159 | 98.3k | ExternUses.push_back(Reg); |
160 | 98.3k | if (MO.isUndef()) |
161 | 128 | UndefUseSet.insert(Reg); |
162 | 98.3k | } |
163 | 142k | if (MO.isKill()) |
164 | 142k | // External def is now killed. |
165 | 39.6k | KilledUseSet.insert(Reg); |
166 | 142k | } |
167 | 826k | } |
168 | 63.1k | |
169 | 127k | for (unsigned i = 0, e = Defs.size(); i != e127k ; ++i64.6k ) { |
170 | 64.6k | MachineOperand &MO = *Defs[i]; |
171 | 64.6k | unsigned Reg = MO.getReg(); |
172 | 64.6k | if (!Reg) |
173 | 0 | continue; |
174 | 64.6k | |
175 | 64.6k | if (64.6k LocalDefSet.insert(Reg).second64.6k ) { |
176 | 62.0k | LocalDefs.push_back(Reg); |
177 | 62.0k | if (MO.isDead()62.0k ) { |
178 | 2.16k | DeadDefSet.insert(Reg); |
179 | 2.16k | } |
180 | 64.6k | } else { |
181 | 2.53k | // Re-defined inside the bundle, it's no longer killed. |
182 | 2.53k | KilledDefSet.erase(Reg); |
183 | 2.53k | if (!MO.isDead()) |
184 | 2.53k | // Previously defined but dead. |
185 | 2.27k | DeadDefSet.erase(Reg); |
186 | 2.53k | } |
187 | 64.6k | |
188 | 64.6k | if (!MO.isDead()64.6k ) { |
189 | 64.9k | for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid()64.9k ; ++SubRegs2.79k ) { |
190 | 2.79k | unsigned SubReg = *SubRegs; |
191 | 2.79k | if (LocalDefSet.insert(SubReg).second) |
192 | 2.76k | LocalDefs.push_back(SubReg); |
193 | 2.79k | } |
194 | 62.1k | } |
195 | 64.6k | } |
196 | 63.1k | |
197 | 63.1k | Defs.clear(); |
198 | 63.1k | } |
199 | 24.2k | |
200 | 24.2k | SmallSet<unsigned, 32> Added; |
201 | 89.1k | for (unsigned i = 0, e = LocalDefs.size(); i != e89.1k ; ++i64.8k ) { |
202 | 64.8k | unsigned Reg = LocalDefs[i]; |
203 | 64.8k | if (Added.insert(Reg).second64.8k ) { |
204 | 64.8k | // If it's not live beyond end of the bundle, mark it dead. |
205 | 62.6k | bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); |
206 | 64.8k | MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) | |
207 | 64.8k | getImplRegState(true)); |
208 | 64.8k | } |
209 | 64.8k | } |
210 | 24.2k | |
211 | 122k | for (unsigned i = 0, e = ExternUses.size(); i != e122k ; ++i98.3k ) { |
212 | 98.3k | unsigned Reg = ExternUses[i]; |
213 | 98.3k | bool isKill = KilledUseSet.count(Reg); |
214 | 98.3k | bool isUndef = UndefUseSet.count(Reg); |
215 | 98.3k | MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) | |
216 | 98.3k | getImplRegState(true)); |
217 | 98.3k | } |
218 | 24.2k | } |
219 | | |
220 | | /// finalizeBundle - Same functionality as the previous finalizeBundle except |
221 | | /// the last instruction in the bundle is not provided as an input. This is |
222 | | /// used in cases where bundles are pre-determined by marking instructions |
223 | | /// with 'InsideBundle' marker. It returns the MBB instruction iterator that |
224 | | /// points to the end of the bundle. |
225 | | MachineBasicBlock::instr_iterator |
226 | | llvm::finalizeBundle(MachineBasicBlock &MBB, |
227 | 555 | MachineBasicBlock::instr_iterator FirstMI) { |
228 | 555 | MachineBasicBlock::instr_iterator E = MBB.instr_end(); |
229 | 555 | MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI); |
230 | 1.73k | while (LastMI != E && 1.73k LastMI->isInsideBundle()1.73k ) |
231 | 1.18k | ++LastMI; |
232 | 555 | finalizeBundle(MBB, FirstMI, LastMI); |
233 | 555 | return LastMI; |
234 | 555 | } |
235 | | |
236 | | /// finalizeBundles - Finalize instruction bundles in the specified |
237 | | /// MachineFunction. Return true if any bundles are finalized. |
238 | 2.05k | bool llvm::finalizeBundles(MachineFunction &MF) { |
239 | 2.05k | bool Changed = false; |
240 | 4.11k | for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E4.11k ; ++I2.05k ) { |
241 | 2.05k | MachineBasicBlock &MBB = *I; |
242 | 2.05k | MachineBasicBlock::instr_iterator MII = MBB.instr_begin(); |
243 | 2.05k | MachineBasicBlock::instr_iterator MIE = MBB.instr_end(); |
244 | 2.05k | if (MII == MIE) |
245 | 2 | continue; |
246 | 2.05k | assert(!MII->isInsideBundle() && |
247 | 2.05k | "First instr cannot be inside bundle before finalization!"); |
248 | 2.05k | |
249 | 58.5k | for (++MII; MII != MIE58.5k ; ) { |
250 | 56.4k | if (!MII->isInsideBundle()) |
251 | 56.3k | ++MII; |
252 | 71 | else { |
253 | 71 | MII = finalizeBundle(MBB, std::prev(MII)); |
254 | 71 | Changed = true; |
255 | 71 | } |
256 | 56.4k | } |
257 | 2.05k | } |
258 | 2.05k | |
259 | 2.05k | return Changed; |
260 | 2.05k | } |
261 | | |
262 | | //===----------------------------------------------------------------------===// |
263 | | // MachineOperand iterator |
264 | | //===----------------------------------------------------------------------===// |
265 | | |
266 | | MachineOperandIteratorBase::VirtRegInfo |
267 | | MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg, |
268 | 710k | SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops) { |
269 | 710k | VirtRegInfo RI = { false, false, false }; |
270 | 2.54M | for(; isValid()2.54M ; ++*this1.83M ) { |
271 | 1.83M | MachineOperand &MO = deref(); |
272 | 1.83M | if (!MO.isReg() || 1.83M MO.getReg() != Reg1.43M ) |
273 | 1.11M | continue; |
274 | 717k | |
275 | 717k | // Remember each (MI, OpNo) that refers to Reg. |
276 | 717k | if (717k Ops717k ) |
277 | 717k | Ops->push_back(std::make_pair(MO.getParent(), getOperandNo())); |
278 | 717k | |
279 | 717k | // Both defs and uses can read virtual registers. |
280 | 717k | if (MO.readsReg()717k ) { |
281 | 419k | RI.Reads = true; |
282 | 419k | if (MO.isDef()) |
283 | 164 | RI.Tied = true; |
284 | 419k | } |
285 | 717k | |
286 | 717k | // Only defs can write. |
287 | 717k | if (MO.isDef()) |
288 | 298k | RI.Writes = true; |
289 | 419k | else if (419k !RI.Tied && 419k MO.getParent()->isRegTiedToDefOperand(getOperandNo())419k ) |
290 | 917 | RI.Tied = true; |
291 | 1.83M | } |
292 | 710k | return RI; |
293 | 710k | } |
294 | | |
295 | | MachineOperandIteratorBase::PhysRegInfo |
296 | | MachineOperandIteratorBase::analyzePhysReg(unsigned Reg, |
297 | 39.1k | const TargetRegisterInfo *TRI) { |
298 | 39.1k | bool AllDefsDead = true; |
299 | 39.1k | PhysRegInfo PRI = {false, false, false, false, false, false, false, false}; |
300 | 39.1k | |
301 | 39.1k | assert(TargetRegisterInfo::isPhysicalRegister(Reg) && |
302 | 39.1k | "analyzePhysReg not given a physical register!"); |
303 | 180k | for (; isValid()180k ; ++*this141k ) { |
304 | 141k | MachineOperand &MO = deref(); |
305 | 141k | |
306 | 141k | if (MO.isRegMask() && 141k MO.clobbersPhysReg(Reg)299 ) { |
307 | 272 | PRI.Clobbered = true; |
308 | 272 | continue; |
309 | 272 | } |
310 | 140k | |
311 | 140k | if (140k !MO.isReg()140k ) |
312 | 82.5k | continue; |
313 | 58.2k | |
314 | 58.2k | unsigned MOReg = MO.getReg(); |
315 | 58.2k | if (!MOReg || 58.2k !TargetRegisterInfo::isPhysicalRegister(MOReg)48.8k ) |
316 | 15.1k | continue; |
317 | 43.1k | |
318 | 43.1k | if (43.1k !TRI->regsOverlap(MOReg, Reg)43.1k ) |
319 | 6.01k | continue; |
320 | 37.1k | |
321 | 37.1k | bool Covered = TRI->isSuperRegisterEq(Reg, MOReg); |
322 | 37.1k | if (MO.readsReg()37.1k ) { |
323 | 644 | PRI.Read = true; |
324 | 644 | if (Covered644 ) { |
325 | 638 | PRI.FullyRead = true; |
326 | 638 | if (MO.isKill()) |
327 | 551 | PRI.Killed = true; |
328 | 638 | } |
329 | 37.1k | } else if (36.5k MO.isDef()36.5k ) { |
330 | 36.5k | PRI.Defined = true; |
331 | 36.5k | if (Covered) |
332 | 36.4k | PRI.FullyDefined = true; |
333 | 36.5k | if (!MO.isDead()) |
334 | 35.4k | AllDefsDead = false; |
335 | 36.5k | } |
336 | 141k | } |
337 | 39.1k | |
338 | 39.1k | if (AllDefsDead39.1k ) { |
339 | 3.69k | if (PRI.FullyDefined || 3.69k PRI.Clobbered2.64k ) |
340 | 1.20k | PRI.DeadDef = true; |
341 | 2.49k | else if (2.49k PRI.Defined2.49k ) |
342 | 3 | PRI.PartialDeadDef = true; |
343 | 3.69k | } |
344 | 39.1k | |
345 | 39.1k | return PRI; |
346 | 39.1k | } |