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