blob: fe78acf4d80a1e343d584232576375f97bdd4d80 [file] [log] [blame]
Matthias Braunfbe85ae2016-04-28 03:07:16 +00001//===- DetectDeadLanes.cpp - SubRegister Lane Usage Analysis --*- C++ -*---===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Matthias Braunfbe85ae2016-04-28 03:07:16 +00006//
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:
Francis Visoiu Mistrih93ef1452017-11-30 12:12:19 +000019/// %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.
Matthias Braunfbe85ae2016-04-28 03:07:16 +000025//
26//===----------------------------------------------------------------------===//
27
28#include <deque>
29#include <vector>
30
31#include "llvm/ADT/BitVector.h"
Matthias Braun22152ac2016-05-06 22:43:50 +000032#include "llvm/ADT/SetVector.h"
Matthias Braunfbe85ae2016-04-28 03:07:16 +000033#include "llvm/CodeGen/MachineFunctionPass.h"
34#include "llvm/CodeGen/MachineRegisterInfo.h"
35#include "llvm/CodeGen/Passes.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000036#include "llvm/CodeGen/TargetRegisterInfo.h"
37#include "llvm/CodeGen/TargetSubtargetInfo.h"
Matthias Braunfbe85ae2016-04-28 03:07:16 +000038#include "llvm/InitializePasses.h"
39#include "llvm/Pass.h"
40#include "llvm/PassRegistry.h"
41#include "llvm/Support/Debug.h"
42#include "llvm/Support/raw_ostream.h"
Matthias Braunfbe85ae2016-04-28 03:07:16 +000043
44using namespace llvm;
45
46#define DEBUG_TYPE "detect-dead-lanes"
47
48namespace {
49
50/// Contains a bitmask of which lanes of a given virtual register are
51/// defined and which ones are actually used.
52struct VRegInfo {
53 LaneBitmask UsedLanes;
54 LaneBitmask DefinedLanes;
55};
56
57class DetectDeadLanes : public MachineFunctionPass {
58public:
59 bool runOnMachineFunction(MachineFunction &MF) override;
60
61 static char ID;
62 DetectDeadLanes() : MachineFunctionPass(ID) {}
63
Mehdi Amini117296c2016-10-01 02:56:57 +000064 StringRef getPassName() const override { return "Detect Dead Lanes"; }
Matthias Braunfbe85ae2016-04-28 03:07:16 +000065
Matt Arsenault3698ca22016-06-15 00:25:09 +000066 void getAnalysisUsage(AnalysisUsage &AU) const override {
67 AU.setPreservesCFG();
68 MachineFunctionPass::getAnalysisUsage(AU);
69 }
70
Matthias Braunfbe85ae2016-04-28 03:07:16 +000071private:
72 /// Add used lane bits on the register used by operand \p MO. This translates
73 /// the bitmask based on the operands subregister, and puts the register into
74 /// the worklist if any new bits were added.
75 void addUsedLanesOnOperand(const MachineOperand &MO, LaneBitmask UsedLanes);
76
77 /// Given a bitmask \p UsedLanes for the used lanes on a def output of a
78 /// COPY-like instruction determine the lanes used on the use operands
79 /// and call addUsedLanesOnOperand() for them.
Matthias Braun22152ac2016-05-06 22:43:50 +000080 void transferUsedLanesStep(const MachineInstr &MI, LaneBitmask UsedLanes);
Matthias Braunfbe85ae2016-04-28 03:07:16 +000081
82 /// Given a use regiser operand \p Use and a mask of defined lanes, check
Matthias Braun8f429ea2016-05-06 22:43:46 +000083 /// if the operand belongs to a lowersToCopies() instruction, transfer the
Matthias Braunfbe85ae2016-04-28 03:07:16 +000084 /// mask to the def and put the instruction into the worklist.
85 void transferDefinedLanesStep(const MachineOperand &Use,
86 LaneBitmask DefinedLanes);
87
88 /// Given a mask \p DefinedLanes of lanes defined at operand \p OpNum
89 /// of COPY-like instruction, determine which lanes are defined at the output
90 /// operand \p Def.
91 LaneBitmask transferDefinedLanes(const MachineOperand &Def, unsigned OpNum,
Matthias Braun8f429ea2016-05-06 22:43:46 +000092 LaneBitmask DefinedLanes) const;
Matthias Braunfbe85ae2016-04-28 03:07:16 +000093
Matthias Braun22152ac2016-05-06 22:43:50 +000094 /// Given a mask \p UsedLanes used from the output of instruction \p MI
95 /// determine which lanes are used from operand \p MO of this instruction.
96 LaneBitmask transferUsedLanes(const MachineInstr &MI, LaneBitmask UsedLanes,
97 const MachineOperand &MO) const;
98
99 bool runOnce(MachineFunction &MF);
100
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000101 LaneBitmask determineInitialDefinedLanes(unsigned Reg);
102 LaneBitmask determineInitialUsedLanes(unsigned Reg);
103
Matthias Braun22152ac2016-05-06 22:43:50 +0000104 bool isUndefRegAtInput(const MachineOperand &MO,
105 const VRegInfo &RegInfo) const;
106
107 bool isUndefInput(const MachineOperand &MO, bool *CrossCopy) const;
108
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000109 const MachineRegisterInfo *MRI;
110 const TargetRegisterInfo *TRI;
111
112 void PutInWorklist(unsigned RegIdx) {
113 if (WorklistMembers.test(RegIdx))
114 return;
115 WorklistMembers.set(RegIdx);
116 Worklist.push_back(RegIdx);
117 }
118
119 VRegInfo *VRegInfos;
120 /// Worklist containing virtreg indexes.
121 std::deque<unsigned> Worklist;
122 BitVector WorklistMembers;
123 /// This bitvector is set for each vreg index where the vreg is defined
124 /// by an instruction where lowersToCopies()==true.
125 BitVector DefinedByCopy;
126};
127
128} // end anonymous namespace
129
130char DetectDeadLanes::ID = 0;
131char &llvm::DetectDeadLanesID = DetectDeadLanes::ID;
132
Matthias Braun1527baa2017-05-25 21:26:32 +0000133INITIALIZE_PASS(DetectDeadLanes, DEBUG_TYPE, "Detect Dead Lanes", false, false)
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000134
135/// Returns true if \p MI will get lowered to a series of COPY instructions.
136/// We call this a COPY-like instruction.
137static bool lowersToCopies(const MachineInstr &MI) {
138 // Note: We could support instructions with MCInstrDesc::isRegSequenceLike(),
139 // isExtractSubRegLike(), isInsertSubregLike() in the future even though they
140 // are not lowered to a COPY.
141 switch (MI.getOpcode()) {
142 case TargetOpcode::COPY:
143 case TargetOpcode::PHI:
144 case TargetOpcode::INSERT_SUBREG:
145 case TargetOpcode::REG_SEQUENCE:
146 case TargetOpcode::EXTRACT_SUBREG:
147 return true;
148 }
149 return false;
150}
151
152static bool isCrossCopy(const MachineRegisterInfo &MRI,
153 const MachineInstr &MI,
154 const TargetRegisterClass *DstRC,
155 const MachineOperand &MO) {
156 assert(lowersToCopies(MI));
157 unsigned SrcReg = MO.getReg();
158 const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
159 if (DstRC == SrcRC)
160 return false;
161
162 unsigned SrcSubIdx = MO.getSubReg();
163
164 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
165 unsigned DstSubIdx = 0;
166 switch (MI.getOpcode()) {
167 case TargetOpcode::INSERT_SUBREG:
168 if (MI.getOperandNo(&MO) == 2)
169 DstSubIdx = MI.getOperand(3).getImm();
170 break;
171 case TargetOpcode::REG_SEQUENCE: {
172 unsigned OpNum = MI.getOperandNo(&MO);
173 DstSubIdx = MI.getOperand(OpNum+1).getImm();
174 break;
175 }
176 case TargetOpcode::EXTRACT_SUBREG: {
177 unsigned SubReg = MI.getOperand(2).getImm();
178 SrcSubIdx = TRI.composeSubRegIndices(SubReg, SrcSubIdx);
179 }
180 }
181
182 unsigned PreA, PreB; // Unused.
183 if (SrcSubIdx && DstSubIdx)
184 return !TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA,
185 PreB);
186 if (SrcSubIdx)
187 return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx);
188 if (DstSubIdx)
189 return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx);
190 return !TRI.getCommonSubClass(SrcRC, DstRC);
191}
192
193void DetectDeadLanes::addUsedLanesOnOperand(const MachineOperand &MO,
194 LaneBitmask UsedLanes) {
195 if (!MO.readsReg())
196 return;
197 unsigned MOReg = MO.getReg();
198 if (!TargetRegisterInfo::isVirtualRegister(MOReg))
199 return;
200
201 unsigned MOSubReg = MO.getSubReg();
202 if (MOSubReg != 0)
203 UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
204 UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
205
206 unsigned MORegIdx = TargetRegisterInfo::virtReg2Index(MOReg);
207 VRegInfo &MORegInfo = VRegInfos[MORegIdx];
208 LaneBitmask PrevUsedLanes = MORegInfo.UsedLanes;
209 // Any change at all?
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000210 if ((UsedLanes & ~PrevUsedLanes).none())
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000211 return;
212
213 // Set UsedLanes and remember instruction for further propagation.
214 MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
215 if (DefinedByCopy.test(MORegIdx))
216 PutInWorklist(MORegIdx);
217}
218
Matthias Braun22152ac2016-05-06 22:43:50 +0000219void DetectDeadLanes::transferUsedLanesStep(const MachineInstr &MI,
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000220 LaneBitmask UsedLanes) {
Matthias Braun22152ac2016-05-06 22:43:50 +0000221 for (const MachineOperand &MO : MI.uses()) {
222 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
223 continue;
224 LaneBitmask UsedOnMO = transferUsedLanes(MI, UsedLanes, MO);
225 addUsedLanesOnOperand(MO, UsedOnMO);
226 }
227}
228
229LaneBitmask DetectDeadLanes::transferUsedLanes(const MachineInstr &MI,
230 LaneBitmask UsedLanes,
231 const MachineOperand &MO) const {
232 unsigned OpNum = MI.getOperandNo(&MO);
233 assert(lowersToCopies(MI) && DefinedByCopy[
234 TargetRegisterInfo::virtReg2Index(MI.getOperand(0).getReg())]);
235
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000236 switch (MI.getOpcode()) {
237 case TargetOpcode::COPY:
238 case TargetOpcode::PHI:
Matthias Braun22152ac2016-05-06 22:43:50 +0000239 return UsedLanes;
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000240 case TargetOpcode::REG_SEQUENCE: {
Matthias Braun22152ac2016-05-06 22:43:50 +0000241 assert(OpNum % 2 == 1);
242 unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
243 return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000244 }
245 case TargetOpcode::INSERT_SUBREG: {
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000246 unsigned SubIdx = MI.getOperand(3).getImm();
247 LaneBitmask MO2UsedLanes =
248 TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
Matthias Braun22152ac2016-05-06 22:43:50 +0000249 if (OpNum == 2)
250 return MO2UsedLanes;
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000251
Matthias Braun22152ac2016-05-06 22:43:50 +0000252 const MachineOperand &Def = MI.getOperand(0);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000253 unsigned DefReg = Def.getReg();
254 const TargetRegisterClass *RC = MRI->getRegClass(DefReg);
255 LaneBitmask MO1UsedLanes;
256 if (RC->CoveredBySubRegs)
257 MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
258 else
259 MO1UsedLanes = RC->LaneMask;
Matthias Braun22152ac2016-05-06 22:43:50 +0000260
261 assert(OpNum == 1);
262 return MO1UsedLanes;
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000263 }
264 case TargetOpcode::EXTRACT_SUBREG: {
Matthias Braun22152ac2016-05-06 22:43:50 +0000265 assert(OpNum == 1);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000266 unsigned SubIdx = MI.getOperand(2).getImm();
Matthias Braun22152ac2016-05-06 22:43:50 +0000267 return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000268 }
269 default:
270 llvm_unreachable("function must be called with COPY-like instruction");
271 }
272}
273
274void DetectDeadLanes::transferDefinedLanesStep(const MachineOperand &Use,
275 LaneBitmask DefinedLanes) {
276 if (!Use.readsReg())
277 return;
278 // Check whether the operand writes a vreg and is part of a COPY-like
279 // instruction.
280 const MachineInstr &MI = *Use.getParent();
281 if (MI.getDesc().getNumDefs() != 1)
282 return;
283 // FIXME: PATCHPOINT instructions announce a Def that does not always exist,
284 // they really need to be modeled differently!
285 if (MI.getOpcode() == TargetOpcode::PATCHPOINT)
286 return;
287 const MachineOperand &Def = *MI.defs().begin();
288 unsigned DefReg = Def.getReg();
289 if (!TargetRegisterInfo::isVirtualRegister(DefReg))
290 return;
291 unsigned DefRegIdx = TargetRegisterInfo::virtReg2Index(DefReg);
292 if (!DefinedByCopy.test(DefRegIdx))
293 return;
294
295 unsigned OpNum = MI.getOperandNo(&Use);
296 DefinedLanes =
297 TRI->reverseComposeSubRegIndexLaneMask(Use.getSubReg(), DefinedLanes);
298 DefinedLanes = transferDefinedLanes(Def, OpNum, DefinedLanes);
299
300 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
301 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
302 // Any change at all?
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000303 if ((DefinedLanes & ~PrevDefinedLanes).none())
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000304 return;
305
306 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
307 PutInWorklist(DefRegIdx);
308}
309
310LaneBitmask DetectDeadLanes::transferDefinedLanes(const MachineOperand &Def,
Matthias Braun8f429ea2016-05-06 22:43:46 +0000311 unsigned OpNum, LaneBitmask DefinedLanes) const {
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000312 const MachineInstr &MI = *Def.getParent();
313 // Translate DefinedLanes if necessary.
314 switch (MI.getOpcode()) {
315 case TargetOpcode::REG_SEQUENCE: {
316 unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
317 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
318 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
319 break;
320 }
321 case TargetOpcode::INSERT_SUBREG: {
322 unsigned SubIdx = MI.getOperand(3).getImm();
323 if (OpNum == 2) {
324 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
325 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
326 } else {
327 assert(OpNum == 1 && "INSERT_SUBREG must have two operands");
328 // Ignore lanes defined by operand 2.
329 DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
330 }
331 break;
332 }
333 case TargetOpcode::EXTRACT_SUBREG: {
334 unsigned SubIdx = MI.getOperand(2).getImm();
335 assert(OpNum == 1 && "EXTRACT_SUBREG must have one register operand only");
336 DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
337 break;
338 }
339 case TargetOpcode::COPY:
340 case TargetOpcode::PHI:
341 break;
342 default:
343 llvm_unreachable("function must be called with COPY-like instruction");
344 }
345
Matthias Braun8f429ea2016-05-06 22:43:46 +0000346 assert(Def.getSubReg() == 0 &&
347 "Should not have subregister defs in machine SSA phase");
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000348 DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
349 return DefinedLanes;
350}
351
352LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
353 // Live-In or unused registers have no definition but are considered fully
354 // defined.
355 if (!MRI->hasOneDef(Reg))
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000356 return LaneBitmask::getAll();
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000357
358 const MachineOperand &Def = *MRI->def_begin(Reg);
359 const MachineInstr &DefMI = *Def.getParent();
360 if (lowersToCopies(DefMI)) {
361 // Start optimisatically with no used or defined lanes for copy
362 // instructions. The following dataflow analysis will add more bits.
363 unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
364 DefinedByCopy.set(RegIdx);
365 PutInWorklist(RegIdx);
366
367 if (Def.isDead())
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000368 return LaneBitmask::getNone();
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000369
370 // COPY/PHI can copy across unrelated register classes (example: float/int)
371 // with incompatible subregister structure. Do not include these in the
372 // dataflow analysis since we cannot transfer lanemasks in a meaningful way.
373 const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
374
375 // Determine initially DefinedLanes.
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000376 LaneBitmask DefinedLanes;
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000377 for (const MachineOperand &MO : DefMI.uses()) {
378 if (!MO.isReg() || !MO.readsReg())
379 continue;
380 unsigned MOReg = MO.getReg();
381 if (!MOReg)
382 continue;
383
384 LaneBitmask MODefinedLanes;
385 if (TargetRegisterInfo::isPhysicalRegister(MOReg)) {
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000386 MODefinedLanes = LaneBitmask::getAll();
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000387 } else if (isCrossCopy(*MRI, DefMI, DefRC, MO)) {
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000388 MODefinedLanes = LaneBitmask::getAll();
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000389 } else {
390 assert(TargetRegisterInfo::isVirtualRegister(MOReg));
391 if (MRI->hasOneDef(MOReg)) {
392 const MachineOperand &MODef = *MRI->def_begin(MOReg);
393 const MachineInstr &MODefMI = *MODef.getParent();
394 // Bits from copy-like operations will be added later.
395 if (lowersToCopies(MODefMI) || MODefMI.isImplicitDef())
396 continue;
397 }
398 unsigned MOSubReg = MO.getSubReg();
399 MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
400 MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
401 MOSubReg, MODefinedLanes);
402 }
403
404 unsigned OpNum = DefMI.getOperandNo(&MO);
405 DefinedLanes |= transferDefinedLanes(Def, OpNum, MODefinedLanes);
406 }
407 return DefinedLanes;
408 }
409 if (DefMI.isImplicitDef() || Def.isDead())
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000410 return LaneBitmask::getNone();
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000411
Matthias Braun8f429ea2016-05-06 22:43:46 +0000412 assert(Def.getSubReg() == 0 &&
413 "Should not have subregister defs in machine SSA phase");
414 return MRI->getMaxLaneMaskForVReg(Reg);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000415}
416
417LaneBitmask DetectDeadLanes::determineInitialUsedLanes(unsigned Reg) {
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000418 LaneBitmask UsedLanes = LaneBitmask::getNone();
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000419 for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
420 if (!MO.readsReg())
421 continue;
422
423 const MachineInstr &UseMI = *MO.getParent();
424 if (UseMI.isKill())
425 continue;
426
427 unsigned SubReg = MO.getSubReg();
428 if (lowersToCopies(UseMI)) {
429 assert(UseMI.getDesc().getNumDefs() == 1);
430 const MachineOperand &Def = *UseMI.defs().begin();
431 unsigned DefReg = Def.getReg();
432 // The used lanes of COPY-like instruction operands are determined by the
433 // following dataflow analysis.
434 if (TargetRegisterInfo::isVirtualRegister(DefReg)) {
435 // But ignore copies across incompatible register classes.
436 bool CrossCopy = false;
437 if (lowersToCopies(UseMI)) {
438 const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
439 CrossCopy = isCrossCopy(*MRI, UseMI, DstRC, MO);
Matthias Braun22152ac2016-05-06 22:43:50 +0000440 if (CrossCopy)
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000441 LLVM_DEBUG(dbgs() << "Copy across incompatible classes: " << UseMI);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000442 }
443
444 if (!CrossCopy)
445 continue;
446 }
447 }
448
449 // Shortcut: All lanes are used.
450 if (SubReg == 0)
451 return MRI->getMaxLaneMaskForVReg(Reg);
452
453 UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
454 }
455 return UsedLanes;
456}
457
Matthias Braun22152ac2016-05-06 22:43:50 +0000458bool DetectDeadLanes::isUndefRegAtInput(const MachineOperand &MO,
459 const VRegInfo &RegInfo) const {
460 unsigned SubReg = MO.getSubReg();
461 LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000462 return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
Matthias Braun22152ac2016-05-06 22:43:50 +0000463}
464
465bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
466 bool *CrossCopy) const {
467 if (!MO.isUse())
468 return false;
469 const MachineInstr &MI = *MO.getParent();
470 if (!lowersToCopies(MI))
471 return false;
472 const MachineOperand &Def = MI.getOperand(0);
473 unsigned DefReg = Def.getReg();
474 if (!TargetRegisterInfo::isVirtualRegister(DefReg))
475 return false;
476 unsigned DefRegIdx = TargetRegisterInfo::virtReg2Index(DefReg);
477 if (!DefinedByCopy.test(DefRegIdx))
478 return false;
479
480 const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
481 LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
Krzysztof Parzyszekea9f8ce2016-12-16 19:11:56 +0000482 if (UsedLanes.any())
Matthias Braun22152ac2016-05-06 22:43:50 +0000483 return false;
484
485 unsigned MOReg = MO.getReg();
486 if (TargetRegisterInfo::isVirtualRegister(MOReg)) {
487 const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
488 *CrossCopy = isCrossCopy(*MRI, MI, DstRC, MO);
489 }
490 return true;
491}
492
493bool DetectDeadLanes::runOnce(MachineFunction &MF) {
494 // First pass: Populate defs/uses of vregs with initial values
495 unsigned NumVirtRegs = MRI->getNumVirtRegs();
496 for (unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
497 unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
498
499 // Determine used/defined lanes and add copy instructions to worklist.
500 VRegInfo &Info = VRegInfos[RegIdx];
501 Info.DefinedLanes = determineInitialDefinedLanes(Reg);
502 Info.UsedLanes = determineInitialUsedLanes(Reg);
503 }
504
505 // Iterate as long as defined lanes/used lanes keep changing.
506 while (!Worklist.empty()) {
507 unsigned RegIdx = Worklist.front();
508 Worklist.pop_front();
509 WorklistMembers.reset(RegIdx);
510 VRegInfo &Info = VRegInfos[RegIdx];
511 unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
512
513 // Transfer UsedLanes to operands of DefMI (backwards dataflow).
514 MachineOperand &Def = *MRI->def_begin(Reg);
515 const MachineInstr &MI = *Def.getParent();
516 transferUsedLanesStep(MI, Info.UsedLanes);
517 // Transfer DefinedLanes to users of Reg (forward dataflow).
518 for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg))
519 transferDefinedLanesStep(MO, Info.DefinedLanes);
520 }
521
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000522 LLVM_DEBUG(dbgs() << "Defined/Used lanes:\n"; for (unsigned RegIdx = 0;
523 RegIdx < NumVirtRegs;
524 ++RegIdx) {
525 unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
526 const VRegInfo &Info = VRegInfos[RegIdx];
527 dbgs() << printReg(Reg, nullptr)
528 << " Used: " << PrintLaneMask(Info.UsedLanes)
529 << " Def: " << PrintLaneMask(Info.DefinedLanes) << '\n';
530 } dbgs() << "\n";);
Matthias Braun22152ac2016-05-06 22:43:50 +0000531
532 bool Again = false;
533 // Mark operands as dead/unused.
534 for (MachineBasicBlock &MBB : MF) {
535 for (MachineInstr &MI : MBB) {
536 for (MachineOperand &MO : MI.operands()) {
537 if (!MO.isReg())
538 continue;
539 unsigned Reg = MO.getReg();
540 if (!TargetRegisterInfo::isVirtualRegister(Reg))
541 continue;
542 unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
543 const VRegInfo &RegInfo = VRegInfos[RegIdx];
Krzysztof Parzyszek91b5cf82016-12-15 14:36:06 +0000544 if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes.none()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000545 LLVM_DEBUG(dbgs()
546 << "Marking operand '" << MO << "' as dead in " << MI);
Matthias Braun22152ac2016-05-06 22:43:50 +0000547 MO.setIsDead();
548 }
549 if (MO.readsReg()) {
550 bool CrossCopy = false;
551 if (isUndefRegAtInput(MO, RegInfo)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000552 LLVM_DEBUG(dbgs()
553 << "Marking operand '" << MO << "' as undef in " << MI);
Matthias Braun22152ac2016-05-06 22:43:50 +0000554 MO.setIsUndef();
555 } else if (isUndefInput(MO, &CrossCopy)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000556 LLVM_DEBUG(dbgs()
557 << "Marking operand '" << MO << "' as undef in " << MI);
Matthias Braun22152ac2016-05-06 22:43:50 +0000558 MO.setIsUndef();
559 if (CrossCopy)
560 Again = true;
561 }
562 }
563 }
564 }
565 }
566
567 return Again;
568}
569
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000570bool 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.
Matthias Braunf1b20c52016-08-24 22:17:45 +0000576 MRI = &MF.getRegInfo();
577 if (!MRI->subRegLivenessEnabled()) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000578 LLVM_DEBUG(dbgs() << "Skipping Detect dead lanes pass\n");
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000579 return false;
580 }
581
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000582 TRI = MRI->getTargetRegisterInfo();
583
584 unsigned NumVirtRegs = MRI->getNumVirtRegs();
585 VRegInfos = new VRegInfo[NumVirtRegs];
586 WorklistMembers.resize(NumVirtRegs);
587 DefinedByCopy.resize(NumVirtRegs);
588
Matthias Braun22152ac2016-05-06 22:43:50 +0000589 bool Again;
590 do {
591 Again = runOnce(MF);
592 } while(Again);
Matthias Braunfbe85ae2016-04-28 03:07:16 +0000593
594 DefinedByCopy.clear();
595 WorklistMembers.clear();
596 delete[] VRegInfos;
597 return true;
598}