1 //===- DetectDeadLanes.cpp - SubRegister Lane Usage Analysis --*- 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 /// \file
10 /// Analysis that tracks defined/used subregister lanes across COPY instructions
11 /// and instructions that get lowered to a COPY (PHI, REG_SEQUENCE,
12 /// INSERT_SUBREG, EXTRACT_SUBREG).
13 /// The information is used to detect dead definitions and the usage of
14 /// (completely) undefined values and mark the operands as such.
15 /// This pass is necessary because the dead/undef status is not obvious anymore
16 /// when subregisters are involved.
17 ///
18 /// Example:
19 /// %0 = some definition
20 /// %1 = IMPLICIT_DEF
21 /// %2 = REG_SEQUENCE %0, sub0, %1, sub1
22 /// %3 = EXTRACT_SUBREG %2, sub1
23 /// = use %3
24 /// The %0 definition is dead and %3 contains an undefined value.
25 //
26 //===----------------------------------------------------------------------===//
27
28 #include "llvm/ADT/BitVector.h"
29 #include "llvm/CodeGen/MachineFunctionPass.h"
30 #include "llvm/CodeGen/MachineRegisterInfo.h"
31 #include "llvm/CodeGen/TargetRegisterInfo.h"
32 #include "llvm/InitializePasses.h"
33 #include "llvm/Pass.h"
34 #include "llvm/Support/Debug.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include <deque>
37
38 using namespace llvm;
39
40 #define DEBUG_TYPE "detect-dead-lanes"
41
42 namespace {
43
44 /// Contains a bitmask of which lanes of a given virtual register are
45 /// defined and which ones are actually used.
46 struct VRegInfo {
47 LaneBitmask UsedLanes;
48 LaneBitmask DefinedLanes;
49 };
50
51 class DetectDeadLanes : public MachineFunctionPass {
52 public:
53 bool runOnMachineFunction(MachineFunction &MF) override;
54
55 static char ID;
DetectDeadLanes()56 DetectDeadLanes() : MachineFunctionPass(ID) {}
57
getPassName() const58 StringRef getPassName() const override { return "Detect Dead Lanes"; }
59
getAnalysisUsage(AnalysisUsage & AU) const60 void getAnalysisUsage(AnalysisUsage &AU) const override {
61 AU.setPreservesCFG();
62 MachineFunctionPass::getAnalysisUsage(AU);
63 }
64
65 private:
66 /// Add used lane bits on the register used by operand \p MO. This translates
67 /// the bitmask based on the operands subregister, and puts the register into
68 /// the worklist if any new bits were added.
69 void addUsedLanesOnOperand(const MachineOperand &MO, LaneBitmask UsedLanes);
70
71 /// Given a bitmask \p UsedLanes for the used lanes on a def output of a
72 /// COPY-like instruction determine the lanes used on the use operands
73 /// and call addUsedLanesOnOperand() for them.
74 void transferUsedLanesStep(const MachineInstr &MI, LaneBitmask UsedLanes);
75
76 /// Given a use regiser operand \p Use and a mask of defined lanes, check
77 /// if the operand belongs to a lowersToCopies() instruction, transfer the
78 /// mask to the def and put the instruction into the worklist.
79 void transferDefinedLanesStep(const MachineOperand &Use,
80 LaneBitmask DefinedLanes);
81
82 /// Given a mask \p DefinedLanes of lanes defined at operand \p OpNum
83 /// of COPY-like instruction, determine which lanes are defined at the output
84 /// operand \p Def.
85 LaneBitmask transferDefinedLanes(const MachineOperand &Def, unsigned OpNum,
86 LaneBitmask DefinedLanes) const;
87
88 /// Given a mask \p UsedLanes used from the output of instruction \p MI
89 /// determine which lanes are used from operand \p MO of this instruction.
90 LaneBitmask transferUsedLanes(const MachineInstr &MI, LaneBitmask UsedLanes,
91 const MachineOperand &MO) const;
92
93 std::pair<bool, bool> runOnce(MachineFunction &MF);
94
95 LaneBitmask determineInitialDefinedLanes(unsigned Reg);
96 LaneBitmask determineInitialUsedLanes(unsigned Reg);
97
98 bool isUndefRegAtInput(const MachineOperand &MO,
99 const VRegInfo &RegInfo) const;
100
101 bool isUndefInput(const MachineOperand &MO, bool *CrossCopy) const;
102
103 const MachineRegisterInfo *MRI;
104 const TargetRegisterInfo *TRI;
105
PutInWorklist(unsigned RegIdx)106 void PutInWorklist(unsigned RegIdx) {
107 if (WorklistMembers.test(RegIdx))
108 return;
109 WorklistMembers.set(RegIdx);
110 Worklist.push_back(RegIdx);
111 }
112
113 VRegInfo *VRegInfos;
114 /// Worklist containing virtreg indexes.
115 std::deque<unsigned> Worklist;
116 BitVector WorklistMembers;
117 /// This bitvector is set for each vreg index where the vreg is defined
118 /// by an instruction where lowersToCopies()==true.
119 BitVector DefinedByCopy;
120 };
121
122 } // end anonymous namespace
123
124 char DetectDeadLanes::ID = 0;
125 char &llvm::DetectDeadLanesID = DetectDeadLanes::ID;
126
127 INITIALIZE_PASS(DetectDeadLanes, DEBUG_TYPE, "Detect Dead Lanes", false, false)
128
129 /// Returns true if \p MI will get lowered to a series of COPY instructions.
130 /// We call this a COPY-like instruction.
lowersToCopies(const MachineInstr & MI)131 static bool lowersToCopies(const MachineInstr &MI) {
132 // Note: We could support instructions with MCInstrDesc::isRegSequenceLike(),
133 // isExtractSubRegLike(), isInsertSubregLike() in the future even though they
134 // are not lowered to a COPY.
135 switch (MI.getOpcode()) {
136 case TargetOpcode::COPY:
137 case TargetOpcode::PHI:
138 case TargetOpcode::INSERT_SUBREG:
139 case TargetOpcode::REG_SEQUENCE:
140 case TargetOpcode::EXTRACT_SUBREG:
141 return true;
142 }
143 return false;
144 }
145
isCrossCopy(const MachineRegisterInfo & MRI,const MachineInstr & MI,const TargetRegisterClass * DstRC,const MachineOperand & MO)146 static bool isCrossCopy(const MachineRegisterInfo &MRI,
147 const MachineInstr &MI,
148 const TargetRegisterClass *DstRC,
149 const MachineOperand &MO) {
150 assert(lowersToCopies(MI));
151 Register SrcReg = MO.getReg();
152 const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
153 if (DstRC == SrcRC)
154 return false;
155
156 unsigned SrcSubIdx = MO.getSubReg();
157
158 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
159 unsigned DstSubIdx = 0;
160 switch (MI.getOpcode()) {
161 case TargetOpcode::INSERT_SUBREG:
162 if (MI.getOperandNo(&MO) == 2)
163 DstSubIdx = MI.getOperand(3).getImm();
164 break;
165 case TargetOpcode::REG_SEQUENCE: {
166 unsigned OpNum = MI.getOperandNo(&MO);
167 DstSubIdx = MI.getOperand(OpNum+1).getImm();
168 break;
169 }
170 case TargetOpcode::EXTRACT_SUBREG: {
171 unsigned SubReg = MI.getOperand(2).getImm();
172 SrcSubIdx = TRI.composeSubRegIndices(SubReg, SrcSubIdx);
173 }
174 }
175
176 unsigned PreA, PreB; // Unused.
177 if (SrcSubIdx && DstSubIdx)
178 return !TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA,
179 PreB);
180 if (SrcSubIdx)
181 return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx);
182 if (DstSubIdx)
183 return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx);
184 return !TRI.getCommonSubClass(SrcRC, DstRC);
185 }
186
addUsedLanesOnOperand(const MachineOperand & MO,LaneBitmask UsedLanes)187 void DetectDeadLanes::addUsedLanesOnOperand(const MachineOperand &MO,
188 LaneBitmask UsedLanes) {
189 if (!MO.readsReg())
190 return;
191 Register MOReg = MO.getReg();
192 if (!MOReg.isVirtual())
193 return;
194
195 unsigned MOSubReg = MO.getSubReg();
196 if (MOSubReg != 0)
197 UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
198 UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
199
200 unsigned MORegIdx = Register::virtReg2Index(MOReg);
201 VRegInfo &MORegInfo = VRegInfos[MORegIdx];
202 LaneBitmask PrevUsedLanes = MORegInfo.UsedLanes;
203 // Any change at all?
204 if ((UsedLanes & ~PrevUsedLanes).none())
205 return;
206
207 // Set UsedLanes and remember instruction for further propagation.
208 MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
209 if (DefinedByCopy.test(MORegIdx))
210 PutInWorklist(MORegIdx);
211 }
212
transferUsedLanesStep(const MachineInstr & MI,LaneBitmask UsedLanes)213 void DetectDeadLanes::transferUsedLanesStep(const MachineInstr &MI,
214 LaneBitmask UsedLanes) {
215 for (const MachineOperand &MO : MI.uses()) {
216 if (!MO.isReg() || !MO.getReg().isVirtual())
217 continue;
218 LaneBitmask UsedOnMO = transferUsedLanes(MI, UsedLanes, MO);
219 addUsedLanesOnOperand(MO, UsedOnMO);
220 }
221 }
222
transferUsedLanes(const MachineInstr & MI,LaneBitmask UsedLanes,const MachineOperand & MO) const223 LaneBitmask DetectDeadLanes::transferUsedLanes(const MachineInstr &MI,
224 LaneBitmask UsedLanes,
225 const MachineOperand &MO) const {
226 unsigned OpNum = MI.getOperandNo(&MO);
227 assert(lowersToCopies(MI) &&
228 DefinedByCopy[Register::virtReg2Index(MI.getOperand(0).getReg())]);
229
230 switch (MI.getOpcode()) {
231 case TargetOpcode::COPY:
232 case TargetOpcode::PHI:
233 return UsedLanes;
234 case TargetOpcode::REG_SEQUENCE: {
235 assert(OpNum % 2 == 1);
236 unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
237 return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
238 }
239 case TargetOpcode::INSERT_SUBREG: {
240 unsigned SubIdx = MI.getOperand(3).getImm();
241 LaneBitmask MO2UsedLanes =
242 TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
243 if (OpNum == 2)
244 return MO2UsedLanes;
245
246 const MachineOperand &Def = MI.getOperand(0);
247 Register DefReg = Def.getReg();
248 const TargetRegisterClass *RC = MRI->getRegClass(DefReg);
249 LaneBitmask MO1UsedLanes;
250 if (RC->CoveredBySubRegs)
251 MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
252 else
253 MO1UsedLanes = RC->LaneMask;
254
255 assert(OpNum == 1);
256 return MO1UsedLanes;
257 }
258 case TargetOpcode::EXTRACT_SUBREG: {
259 assert(OpNum == 1);
260 unsigned SubIdx = MI.getOperand(2).getImm();
261 return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
262 }
263 default:
264 llvm_unreachable("function must be called with COPY-like instruction");
265 }
266 }
267
transferDefinedLanesStep(const MachineOperand & Use,LaneBitmask DefinedLanes)268 void DetectDeadLanes::transferDefinedLanesStep(const MachineOperand &Use,
269 LaneBitmask DefinedLanes) {
270 if (!Use.readsReg())
271 return;
272 // Check whether the operand writes a vreg and is part of a COPY-like
273 // instruction.
274 const MachineInstr &MI = *Use.getParent();
275 if (MI.getDesc().getNumDefs() != 1)
276 return;
277 // FIXME: PATCHPOINT instructions announce a Def that does not always exist,
278 // they really need to be modeled differently!
279 if (MI.getOpcode() == TargetOpcode::PATCHPOINT)
280 return;
281 const MachineOperand &Def = *MI.defs().begin();
282 Register DefReg = Def.getReg();
283 if (!DefReg.isVirtual())
284 return;
285 unsigned DefRegIdx = Register::virtReg2Index(DefReg);
286 if (!DefinedByCopy.test(DefRegIdx))
287 return;
288
289 unsigned OpNum = MI.getOperandNo(&Use);
290 DefinedLanes =
291 TRI->reverseComposeSubRegIndexLaneMask(Use.getSubReg(), DefinedLanes);
292 DefinedLanes = transferDefinedLanes(Def, OpNum, DefinedLanes);
293
294 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
295 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
296 // Any change at all?
297 if ((DefinedLanes & ~PrevDefinedLanes).none())
298 return;
299
300 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
301 PutInWorklist(DefRegIdx);
302 }
303
transferDefinedLanes(const MachineOperand & Def,unsigned OpNum,LaneBitmask DefinedLanes) const304 LaneBitmask DetectDeadLanes::transferDefinedLanes(const MachineOperand &Def,
305 unsigned OpNum, LaneBitmask DefinedLanes) const {
306 const MachineInstr &MI = *Def.getParent();
307 // Translate DefinedLanes if necessary.
308 switch (MI.getOpcode()) {
309 case TargetOpcode::REG_SEQUENCE: {
310 unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
311 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
312 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
313 break;
314 }
315 case TargetOpcode::INSERT_SUBREG: {
316 unsigned SubIdx = MI.getOperand(3).getImm();
317 if (OpNum == 2) {
318 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
319 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
320 } else {
321 assert(OpNum == 1 && "INSERT_SUBREG must have two operands");
322 // Ignore lanes defined by operand 2.
323 DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
324 }
325 break;
326 }
327 case TargetOpcode::EXTRACT_SUBREG: {
328 unsigned SubIdx = MI.getOperand(2).getImm();
329 assert(OpNum == 1 && "EXTRACT_SUBREG must have one register operand only");
330 DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
331 break;
332 }
333 case TargetOpcode::COPY:
334 case TargetOpcode::PHI:
335 break;
336 default:
337 llvm_unreachable("function must be called with COPY-like instruction");
338 }
339
340 assert(Def.getSubReg() == 0 &&
341 "Should not have subregister defs in machine SSA phase");
342 DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
343 return DefinedLanes;
344 }
345
determineInitialDefinedLanes(unsigned Reg)346 LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
347 // Live-In or unused registers have no definition but are considered fully
348 // defined.
349 if (!MRI->hasOneDef(Reg))
350 return LaneBitmask::getAll();
351
352 const MachineOperand &Def = *MRI->def_begin(Reg);
353 const MachineInstr &DefMI = *Def.getParent();
354 if (lowersToCopies(DefMI)) {
355 // Start optimisatically with no used or defined lanes for copy
356 // instructions. The following dataflow analysis will add more bits.
357 unsigned RegIdx = Register::virtReg2Index(Reg);
358 DefinedByCopy.set(RegIdx);
359 PutInWorklist(RegIdx);
360
361 if (Def.isDead())
362 return LaneBitmask::getNone();
363
364 // COPY/PHI can copy across unrelated register classes (example: float/int)
365 // with incompatible subregister structure. Do not include these in the
366 // dataflow analysis since we cannot transfer lanemasks in a meaningful way.
367 const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
368
369 // Determine initially DefinedLanes.
370 LaneBitmask DefinedLanes;
371 for (const MachineOperand &MO : DefMI.uses()) {
372 if (!MO.isReg() || !MO.readsReg())
373 continue;
374 Register MOReg = MO.getReg();
375 if (!MOReg)
376 continue;
377
378 LaneBitmask MODefinedLanes;
379 if (MOReg.isPhysical()) {
380 MODefinedLanes = LaneBitmask::getAll();
381 } else if (isCrossCopy(*MRI, DefMI, DefRC, MO)) {
382 MODefinedLanes = LaneBitmask::getAll();
383 } else {
384 assert(MOReg.isVirtual());
385 if (MRI->hasOneDef(MOReg)) {
386 const MachineOperand &MODef = *MRI->def_begin(MOReg);
387 const MachineInstr &MODefMI = *MODef.getParent();
388 // Bits from copy-like operations will be added later.
389 if (lowersToCopies(MODefMI) || MODefMI.isImplicitDef())
390 continue;
391 }
392 unsigned MOSubReg = MO.getSubReg();
393 MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
394 MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
395 MOSubReg, MODefinedLanes);
396 }
397
398 unsigned OpNum = DefMI.getOperandNo(&MO);
399 DefinedLanes |= transferDefinedLanes(Def, OpNum, MODefinedLanes);
400 }
401 return DefinedLanes;
402 }
403 if (DefMI.isImplicitDef() || Def.isDead())
404 return LaneBitmask::getNone();
405
406 assert(Def.getSubReg() == 0 &&
407 "Should not have subregister defs in machine SSA phase");
408 return MRI->getMaxLaneMaskForVReg(Reg);
409 }
410
determineInitialUsedLanes(unsigned Reg)411 LaneBitmask DetectDeadLanes::determineInitialUsedLanes(unsigned Reg) {
412 LaneBitmask UsedLanes = LaneBitmask::getNone();
413 for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
414 if (!MO.readsReg())
415 continue;
416
417 const MachineInstr &UseMI = *MO.getParent();
418 if (UseMI.isKill())
419 continue;
420
421 unsigned SubReg = MO.getSubReg();
422 if (lowersToCopies(UseMI)) {
423 assert(UseMI.getDesc().getNumDefs() == 1);
424 const MachineOperand &Def = *UseMI.defs().begin();
425 Register DefReg = Def.getReg();
426 // The used lanes of COPY-like instruction operands are determined by the
427 // following dataflow analysis.
428 if (DefReg.isVirtual()) {
429 // But ignore copies across incompatible register classes.
430 bool CrossCopy = false;
431 if (lowersToCopies(UseMI)) {
432 const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
433 CrossCopy = isCrossCopy(*MRI, UseMI, DstRC, MO);
434 if (CrossCopy)
435 LLVM_DEBUG(dbgs() << "Copy across incompatible classes: " << UseMI);
436 }
437
438 if (!CrossCopy)
439 continue;
440 }
441 }
442
443 // Shortcut: All lanes are used.
444 if (SubReg == 0)
445 return MRI->getMaxLaneMaskForVReg(Reg);
446
447 UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
448 }
449 return UsedLanes;
450 }
451
isUndefRegAtInput(const MachineOperand & MO,const VRegInfo & RegInfo) const452 bool DetectDeadLanes::isUndefRegAtInput(const MachineOperand &MO,
453 const VRegInfo &RegInfo) const {
454 unsigned SubReg = MO.getSubReg();
455 LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
456 return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
457 }
458
isUndefInput(const MachineOperand & MO,bool * CrossCopy) const459 bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
460 bool *CrossCopy) const {
461 if (!MO.isUse())
462 return false;
463 const MachineInstr &MI = *MO.getParent();
464 if (!lowersToCopies(MI))
465 return false;
466 const MachineOperand &Def = MI.getOperand(0);
467 Register DefReg = Def.getReg();
468 if (!DefReg.isVirtual())
469 return false;
470 unsigned DefRegIdx = Register::virtReg2Index(DefReg);
471 if (!DefinedByCopy.test(DefRegIdx))
472 return false;
473
474 const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
475 LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
476 if (UsedLanes.any())
477 return false;
478
479 Register MOReg = MO.getReg();
480 if (MOReg.isVirtual()) {
481 const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
482 *CrossCopy = isCrossCopy(*MRI, MI, DstRC, MO);
483 }
484 return true;
485 }
486
runOnce(MachineFunction & MF)487 std::pair<bool, bool> DetectDeadLanes::runOnce(MachineFunction &MF) {
488 // First pass: Populate defs/uses of vregs with initial values
489 unsigned NumVirtRegs = MRI->getNumVirtRegs();
490 for (unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
491 Register Reg = Register::index2VirtReg(RegIdx);
492
493 // Determine used/defined lanes and add copy instructions to worklist.
494 VRegInfo &Info = VRegInfos[RegIdx];
495 Info.DefinedLanes = determineInitialDefinedLanes(Reg);
496 Info.UsedLanes = determineInitialUsedLanes(Reg);
497 }
498
499 // Iterate as long as defined lanes/used lanes keep changing.
500 while (!Worklist.empty()) {
501 unsigned RegIdx = Worklist.front();
502 Worklist.pop_front();
503 WorklistMembers.reset(RegIdx);
504 VRegInfo &Info = VRegInfos[RegIdx];
505 Register Reg = Register::index2VirtReg(RegIdx);
506
507 // Transfer UsedLanes to operands of DefMI (backwards dataflow).
508 MachineOperand &Def = *MRI->def_begin(Reg);
509 const MachineInstr &MI = *Def.getParent();
510 transferUsedLanesStep(MI, Info.UsedLanes);
511 // Transfer DefinedLanes to users of Reg (forward dataflow).
512 for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg))
513 transferDefinedLanesStep(MO, Info.DefinedLanes);
514 }
515
516 LLVM_DEBUG({
517 dbgs() << "Defined/Used lanes:\n";
518 for (unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
519 Register Reg = Register::index2VirtReg(RegIdx);
520 const VRegInfo &Info = VRegInfos[RegIdx];
521 dbgs() << printReg(Reg, nullptr)
522 << " Used: " << PrintLaneMask(Info.UsedLanes)
523 << " Def: " << PrintLaneMask(Info.DefinedLanes) << '\n';
524 }
525 dbgs() << "\n";
526 });
527
528 bool Changed = false;
529 bool Again = false;
530 // Mark operands as dead/unused.
531 for (MachineBasicBlock &MBB : MF) {
532 for (MachineInstr &MI : MBB) {
533 for (MachineOperand &MO : MI.operands()) {
534 if (!MO.isReg())
535 continue;
536 Register Reg = MO.getReg();
537 if (!Reg.isVirtual())
538 continue;
539 unsigned RegIdx = Register::virtReg2Index(Reg);
540 const VRegInfo &RegInfo = VRegInfos[RegIdx];
541 if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes.none()) {
542 LLVM_DEBUG(dbgs()
543 << "Marking operand '" << MO << "' as dead in " << MI);
544 MO.setIsDead();
545 Changed = true;
546 }
547 if (MO.readsReg()) {
548 bool CrossCopy = false;
549 if (isUndefRegAtInput(MO, RegInfo)) {
550 LLVM_DEBUG(dbgs()
551 << "Marking operand '" << MO << "' as undef in " << MI);
552 MO.setIsUndef();
553 Changed = true;
554 } else if (isUndefInput(MO, &CrossCopy)) {
555 LLVM_DEBUG(dbgs()
556 << "Marking operand '" << MO << "' as undef in " << MI);
557 MO.setIsUndef();
558 Changed = true;
559 if (CrossCopy)
560 Again = true;
561 }
562 }
563 }
564 }
565 }
566
567 return std::make_pair(Changed, Again);
568 }
569
runOnMachineFunction(MachineFunction & MF)570 bool DetectDeadLanes::runOnMachineFunction(MachineFunction &MF) {
571 // Don't bother if we won't track subregister liveness later. This pass is
572 // required for correctness if subregister liveness is enabled because the
573 // register coalescer cannot deal with hidden dead defs. However without
574 // subregister liveness enabled, the expected benefits of this pass are small
575 // so we safe the compile time.
576 MRI = &MF.getRegInfo();
577 if (!MRI->subRegLivenessEnabled()) {
578 LLVM_DEBUG(dbgs() << "Skipping Detect dead lanes pass\n");
579 return false;
580 }
581
582 TRI = MRI->getTargetRegisterInfo();
583
584 unsigned NumVirtRegs = MRI->getNumVirtRegs();
585 VRegInfos = new VRegInfo[NumVirtRegs];
586 WorklistMembers.resize(NumVirtRegs);
587 DefinedByCopy.resize(NumVirtRegs);
588
589 bool Changed = false;
590 bool Again;
591 do {
592 bool LocalChanged;
593 std::tie(LocalChanged, Again) = runOnce(MF);
594 Changed |= LocalChanged;
595 } while(Again);
596
597 DefinedByCopy.clear();
598 WorklistMembers.clear();
599 delete[] VRegInfos;
600 return Changed;
601 }
602