LLVM 24.0.0git
SIOptimizeVGPRLiveRange.cpp
Go to the documentation of this file.
1//===--------------------- SIOptimizeVGPRLiveRange.cpp -------------------===//
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/// This pass tries to remove unnecessary VGPR live ranges in divergent if-else
11/// structures and waterfall loops.
12///
13/// When we do structurization, we usually transform an if-else into two
14/// successive if-then (with a flow block to do predicate inversion). Consider a
15/// simple case after structurization: A divergent value %a was defined before
16/// if-else and used in both THEN (use in THEN is optional) and ELSE part:
17/// bb.if:
18/// %a = ...
19/// ...
20/// bb.then:
21/// ... = op %a
22/// ... // %a can be dead here
23/// bb.flow:
24/// ...
25/// bb.else:
26/// ... = %a
27/// ...
28/// bb.endif
29///
30/// As register allocator has no idea of the thread-control-flow, it will just
31/// assume %a would be alive in the whole range of bb.then because of a later
32/// use in bb.else. On AMDGPU architecture, the VGPR is accessed with respect
33/// to exec mask. For this if-else case, the lanes active in bb.then will be
34/// inactive in bb.else, and vice-versa. So we are safe to say that %a was dead
35/// after the last use in bb.then until the end of the block. The reason is
36/// the instructions in bb.then will only overwrite lanes that will never be
37/// accessed in bb.else.
38///
39/// This pass aims to tell register allocator that %a is in-fact dead,
40/// through inserting a phi-node in bb.flow saying that %a is undef when coming
41/// from bb.then, and then replace the uses in the bb.else with the result of
42/// newly inserted phi.
43///
44/// Two key conditions must be met to ensure correctness:
45/// 1.) The def-point should be in the same loop-level as if-else-endif to make
46/// sure the second loop iteration still get correct data.
47/// 2.) There should be no further uses after the IF-ELSE region.
48///
49///
50/// Waterfall loops get inserted around instructions that use divergent values
51/// but can only be executed with a uniform value. For example an indirect call
52/// to a divergent address:
53/// bb.start:
54/// %a = ...
55/// %fun = ...
56/// ...
57/// bb.loop:
58/// call %fun (%a)
59/// ... // %a can be dead here
60/// loop %bb.loop
61///
62/// The loop block is executed multiple times, but it is run exactly once for
63/// each active lane. Similar to the if-else case, the register allocator
64/// assumes that %a is live throughout the loop as it is used again in the next
65/// iteration. If %a is a VGPR that is unused after the loop, it does not need
66/// to be live after its last use in the loop block. By inserting a phi-node at
67/// the start of bb.loop that is undef when coming from bb.loop, the register
68/// allocation knows that the value of %a does not need to be preserved through
69/// iterations of the loop.
70///
71//
72//===----------------------------------------------------------------------===//
73
75#include "AMDGPU.h"
76#include "GCNSubtarget.h"
82#include "llvm/IR/Dominators.h"
84
85using namespace llvm;
86
87#define DEBUG_TYPE "si-opt-vgpr-liverange"
88
89namespace {
90
91class SIOptimizeVGPRLiveRange {
92private:
93 const SIRegisterInfo *TRI = nullptr;
94 const SIInstrInfo *TII = nullptr;
95 LiveVariables *LV = nullptr;
96 MachineDominatorTree *MDT = nullptr;
97 const MachineLoopInfo *Loops = nullptr;
98 MachineRegisterInfo *MRI = nullptr;
99
100public:
101 SIOptimizeVGPRLiveRange(LiveVariables *LV, MachineDominatorTree *MDT,
103 : LV(LV), MDT(MDT), Loops(Loops) {}
104 bool run(MachineFunction &MF);
105
106 MachineBasicBlock *getElseTarget(MachineBasicBlock *MBB) const;
107
108 void collectElseRegionBlocks(MachineBasicBlock *Flow,
109 MachineBasicBlock *Endif,
111
112 void
113 collectCandidateRegisters(MachineBasicBlock *If, MachineBasicBlock *Flow,
114 MachineBasicBlock *Endif,
116 SmallVectorImpl<Register> &CandidateRegs) const;
117
118 void collectWaterfallCandidateRegisters(
119 MachineBasicBlock *LoopHeader, MachineBasicBlock *LoopEnd,
120 SmallSetVector<Register, 16> &CandidateRegs,
122 SmallVectorImpl<MachineInstr *> &Instructions) const;
123
124 void findNonPHIUsesInBlock(Register Reg, MachineBasicBlock *MBB,
126
127 void updateLiveRangeInThenRegion(Register Reg, MachineBasicBlock *If,
128 MachineBasicBlock *Flow) const;
129
130 void updateLiveRangeInElseRegion(
132 MachineBasicBlock *Endif,
134
135 void
136 optimizeLiveRange(Register Reg, MachineBasicBlock *If,
139
140 void optimizeWaterfallLiveRange(
141 Register Reg, MachineBasicBlock *LoopHeader,
143 SmallVectorImpl<MachineInstr *> &Instructions) const;
144};
145
146class SIOptimizeVGPRLiveRangeLegacy : public MachineFunctionPass {
147public:
148 static char ID;
149
150 SIOptimizeVGPRLiveRangeLegacy() : MachineFunctionPass(ID) {}
151
152 bool runOnMachineFunction(MachineFunction &MF) override;
153
154 StringRef getPassName() const override {
155 return "SI Optimize VGPR LiveRange";
156 }
157
158 void getAnalysisUsage(AnalysisUsage &AU) const override {
159 AU.setPreservesCFG();
165 }
166
167 MachineFunctionProperties getRequiredProperties() const override {
168 return MachineFunctionProperties().setIsSSA();
169 }
170
171 MachineFunctionProperties getClearedProperties() const override {
172 return MachineFunctionProperties().setNoPHIs();
173 }
174};
175
176} // end anonymous namespace
177
178// Check whether the MBB is a else flow block and get the branching target which
179// is the Endif block
181SIOptimizeVGPRLiveRange::getElseTarget(MachineBasicBlock *MBB) const {
182 for (auto &BR : MBB->terminators()) {
183 if (BR.getOpcode() == AMDGPU::SI_ELSE)
184 return BR.getOperand(2).getMBB();
185 }
186 return nullptr;
187}
188
189void SIOptimizeVGPRLiveRange::collectElseRegionBlocks(
190 MachineBasicBlock *Flow, MachineBasicBlock *Endif,
191 SmallSetVector<MachineBasicBlock *, 16> &Blocks) const {
192 assert(Flow != Endif);
193
194 MachineBasicBlock *MBB = Endif;
195 unsigned Cur = 0;
196 while (MBB) {
197 for (auto *Pred : MBB->predecessors()) {
198 if (Pred != Flow)
199 Blocks.insert(Pred);
200 }
201
202 if (Cur < Blocks.size())
203 MBB = Blocks[Cur++];
204 else
205 MBB = nullptr;
206 }
207
208 LLVM_DEBUG({
209 dbgs() << "Found Else blocks: ";
210 for (auto *MBB : Blocks)
211 dbgs() << printMBBReference(*MBB) << ' ';
212 dbgs() << '\n';
213 });
214}
215
216/// Find the instructions(excluding phi) in \p MBB that uses the \p Reg.
217void SIOptimizeVGPRLiveRange::findNonPHIUsesInBlock(
218 Register Reg, MachineBasicBlock *MBB,
219 SmallVectorImpl<MachineInstr *> &Uses) const {
220 for (auto &UseMI : MRI->use_nodbg_instructions(Reg)) {
221 if (UseMI.getParent() == MBB && !UseMI.isPHI() &&
222 UseMI.readsVirtualRegister(Reg))
223 Uses.push_back(&UseMI);
224 }
225}
226
227/// Collect the killed registers in the ELSE region which are not alive through
228/// the whole THEN region.
229void SIOptimizeVGPRLiveRange::collectCandidateRegisters(
230 MachineBasicBlock *If, MachineBasicBlock *Flow, MachineBasicBlock *Endif,
231 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks,
232 SmallVectorImpl<Register> &CandidateRegs) const {
233
234 SmallSet<Register, 8> KillsInElse;
235
236 for (auto *Else : ElseBlocks) {
237 for (auto &MI : Else->instrs()) {
238 if (MI.isDebugInstr())
239 continue;
240
241 for (auto &MO : MI.operands()) {
242 if (!MO.isReg() || !MO.getReg() || MO.isDef())
243 continue;
244
245 Register MOReg = MO.getReg();
246 // We can only optimize AGPR/VGPR virtual register
247 if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg))
248 continue;
249
250 if (MO.readsReg()) {
251 LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg);
252 const MachineBasicBlock *DefMBB = MRI->getDefBlock(MOReg);
253 // Make sure two conditions are met:
254 // a.) the value is defined before/in the IF block
255 // b.) should be defined in the same loop-level.
256 if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) &&
257 Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If)) {
258 // Check if the register is live into the endif block. If not,
259 // consider it killed in the else region.
260 LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg);
261 if (!VI.isLiveIn(*Endif, MOReg, *MRI)) {
262 KillsInElse.insert(MOReg);
263 } else {
264 LLVM_DEBUG(dbgs() << "Excluding " << printReg(MOReg, TRI)
265 << " as Live in Endif\n");
266 }
267 }
268 }
269 }
270 }
271 }
272
273 // Check the phis in the Endif, looking for value coming from the ELSE
274 // region. Make sure the phi-use is the last use.
275 for (auto &MI : Endif->phis()) {
276 for (unsigned Idx = 1; Idx < MI.getNumOperands(); Idx += 2) {
277 auto &MO = MI.getOperand(Idx);
278 auto *Pred = MI.getOperand(Idx + 1).getMBB();
279 if (Pred == Flow)
280 continue;
281 assert(ElseBlocks.contains(Pred) && "Should be from Else region\n");
282
283 if (!MO.isReg() || !MO.getReg() || MO.isUndef())
284 continue;
285
286 Register Reg = MO.getReg();
287 if (Reg.isPhysical() || !TRI->isVectorRegister(*MRI, Reg))
288 continue;
289
290 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
291
292 if (VI.isLiveIn(*Endif, Reg, *MRI)) {
293 LLVM_DEBUG(dbgs() << "Excluding " << printReg(Reg, TRI)
294 << " as Live in Endif\n");
295 continue;
296 }
297 // Make sure two conditions are met:
298 // a.) the value is defined before/in the IF block
299 // b.) should be defined in the same loop-level.
300 const MachineBasicBlock *DefMBB = MRI->getDefBlock(Reg);
301 if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) &&
302 Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If))
303 KillsInElse.insert(Reg);
304 }
305 }
306
307 auto IsLiveThroughThen = [&](Register Reg) {
308 for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E;
309 ++I) {
310 if (!I->readsReg())
311 continue;
312 auto *UseMI = I->getParent();
313 auto *UseMBB = UseMI->getParent();
314 if (UseMBB == Flow || UseMBB == Endif) {
315 if (!UseMI->isPHI())
316 return true;
317
318 auto *IncomingMBB = UseMI->getOperand(I.getOperandNo() + 1).getMBB();
319 // The register is live through the path If->Flow or Flow->Endif.
320 // we should not optimize for such cases.
321 if ((UseMBB == Flow && IncomingMBB != If) ||
322 (UseMBB == Endif && IncomingMBB == Flow))
323 return true;
324 }
325 }
326 return false;
327 };
328
329 for (auto Reg : KillsInElse) {
330 if (!IsLiveThroughThen(Reg))
331 CandidateRegs.push_back(Reg);
332 }
333}
334
335/// Collect the registers used in the waterfall loop block that are defined
336/// before.
337void SIOptimizeVGPRLiveRange::collectWaterfallCandidateRegisters(
338 MachineBasicBlock *LoopHeader, MachineBasicBlock *LoopEnd,
339 SmallSetVector<Register, 16> &CandidateRegs,
340 SmallSetVector<MachineBasicBlock *, 2> &Blocks,
341 SmallVectorImpl<MachineInstr *> &Instructions) const {
342
343 // Collect loop instructions, potentially spanning multiple blocks
344 auto *MBB = LoopHeader;
345 for (;;) {
346 Blocks.insert(MBB);
347 for (auto &MI : *MBB) {
348 if (MI.isDebugInstr())
349 continue;
350 Instructions.push_back(&MI);
351 }
352 if (MBB == LoopEnd)
353 break;
354
355 if ((MBB != LoopHeader && MBB->pred_size() != 1) ||
356 (MBB == LoopHeader && MBB->pred_size() != 2) || MBB->succ_size() != 1) {
357 LLVM_DEBUG(dbgs() << "Unexpected edges in CFG, ignoring loop\n");
358 return;
359 }
360
361 MBB = *MBB->succ_begin();
362 }
363
364 for (auto *I : Instructions) {
365 auto &MI = *I;
366
367 for (auto &MO : MI.all_uses()) {
368 if (!MO.getReg())
369 continue;
370
371 Register MOReg = MO.getReg();
372 // We can only optimize AGPR/VGPR virtual register
373 if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg))
374 continue;
375
376 if (MO.readsReg()) {
377 MachineBasicBlock *DefMBB = MRI->getDefBlock(MOReg);
378 // Make sure the value is defined before the LOOP block
379 if (!Blocks.contains(DefMBB) && !CandidateRegs.contains(MOReg)) {
380 // If the variable is used after the loop, the register coalescer will
381 // merge the newly created register and remove the phi node again.
382 // Just do nothing in that case.
383 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(MOReg);
384 bool IsUsed = false;
385 for (auto *Succ : LoopEnd->successors()) {
386 if (!Blocks.contains(Succ) &&
387 OldVarInfo.isLiveIn(*Succ, MOReg, *MRI)) {
388 IsUsed = true;
389 break;
390 }
391 }
392 if (!IsUsed) {
393 LLVM_DEBUG(dbgs() << "Found candidate reg: "
394 << printReg(MOReg, TRI, 0, MRI) << '\n');
395 CandidateRegs.insert(MOReg);
396 } else {
397 LLVM_DEBUG(dbgs() << "Reg is used after loop, ignoring: "
398 << printReg(MOReg, TRI, 0, MRI) << '\n');
399 }
400 }
401 }
402 }
403 }
404}
405
406// Re-calculate the liveness of \p Reg in the THEN-region
407void SIOptimizeVGPRLiveRange::updateLiveRangeInThenRegion(
408 Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow) const {
409 SetVector<MachineBasicBlock *> Blocks;
411
412 // Collect all successors until we see the flow block, where we should
413 // reconverge.
414 while (!WorkList.empty()) {
415 auto *MBB = WorkList.pop_back_val();
416 for (auto *Succ : MBB->successors()) {
417 if (Succ != Flow && Blocks.insert(Succ))
418 WorkList.push_back(Succ);
419 }
420 }
421
422 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
423 for (MachineBasicBlock *MBB : Blocks) {
424 // Clear Live bit, as we will recalculate afterwards
425 LLVM_DEBUG(dbgs() << "Clear AliveBlock " << printMBBReference(*MBB)
426 << '\n');
427 OldVarInfo.AliveBlocks.reset(MBB->getNumber());
428 }
429
430 SmallPtrSet<MachineBasicBlock *, 4> PHIIncoming;
431
432 // Get the blocks the Reg should be alive through
433 for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E;
434 ++I) {
435 auto *UseMI = I->getParent();
436 if (UseMI->isPHI() && I->readsReg()) {
437 if (Blocks.contains(UseMI->getParent()))
438 PHIIncoming.insert(UseMI->getOperand(I.getOperandNo() + 1).getMBB());
439 }
440 }
441
442 for (MachineBasicBlock *MBB : Blocks) {
444 // PHI instructions has been processed before.
445 findNonPHIUsesInBlock(Reg, MBB, Uses);
446
447 if (Uses.size() == 1) {
448 LLVM_DEBUG(dbgs() << "Found one Non-PHI use in "
449 << printMBBReference(*MBB) << '\n');
450 LV->HandleVirtRegUse(Reg, MBB, *(*Uses.begin()));
451 } else if (Uses.size() > 1) {
452 // Process the instructions in-order
453 LLVM_DEBUG(dbgs() << "Found " << Uses.size() << " Non-PHI uses in "
454 << printMBBReference(*MBB) << '\n');
455 for (MachineInstr &MI : *MBB) {
457 LV->HandleVirtRegUse(Reg, MBB, MI);
458 }
459 }
460
461 // Mark Reg alive through the block if this is a PHI incoming block
462 if (PHIIncoming.contains(MBB))
463 LV->MarkVirtRegAliveInBlock(OldVarInfo, MRI->getDefBlock(Reg), MBB);
464 }
465
466 // Set the isKilled flag if we get new Kills in the THEN region.
467 for (auto *MI : OldVarInfo.Kills) {
468 if (Blocks.contains(MI->getParent()))
469 MI->addRegisterKilled(Reg, TRI);
470 }
471}
472
473void SIOptimizeVGPRLiveRange::updateLiveRangeInElseRegion(
474 Register Reg, Register NewReg, MachineBasicBlock *Flow,
475 MachineBasicBlock *Endif,
476 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const {
477 LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg);
478 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
479
480 // Transfer aliveBlocks from Reg to NewReg
481 for (auto *MBB : ElseBlocks) {
482 unsigned BBNum = MBB->getNumber();
483 if (OldVarInfo.AliveBlocks.test(BBNum)) {
484 NewVarInfo.AliveBlocks.set(BBNum);
485 LLVM_DEBUG(dbgs() << "Removing AliveBlock " << printMBBReference(*MBB)
486 << '\n');
487 OldVarInfo.AliveBlocks.reset(BBNum);
488 }
489 }
490
491 // Transfer the possible Kills in ElseBlocks from Reg to NewReg
492 llvm::erase_if(OldVarInfo.Kills, [&](MachineInstr *MI) {
493 if (!ElseBlocks.contains(MI->getParent()))
494 return false;
495 NewVarInfo.Kills.push_back(MI);
496 return true;
497 });
498}
499
500void SIOptimizeVGPRLiveRange::optimizeLiveRange(
501 Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow,
502 MachineBasicBlock *Endif,
503 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const {
504 // Insert a new PHI, marking the value from the THEN region being
505 // undef.
506 LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n');
507 const auto *RC = MRI->getRegClass(Reg);
508 Register NewReg = MRI->createVirtualRegister(RC);
509 Register UndefReg = MRI->createVirtualRegister(RC);
510 MachineInstrBuilder PHI = BuildMI(*Flow, Flow->getFirstNonPHI(), DebugLoc(),
511 TII->get(TargetOpcode::PHI), NewReg);
512 for (auto *Pred : Flow->predecessors()) {
513 if (Pred == If)
514 PHI.addReg(Reg).addMBB(Pred);
515 else
516 PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred);
517 }
518
519 // Replace all uses in the ELSE region or the PHIs in ENDIF block
520 // Use early increment range because setReg() will update the linked list.
521 for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) {
522 auto *UseMI = O.getParent();
523 auto *UseBlock = UseMI->getParent();
524 // Replace uses in Endif block
525 if (UseBlock == Endif) {
526 if (UseMI->isPHI())
527 O.setReg(NewReg);
528 else if (UseMI->isDebugInstr())
529 continue;
530 else {
531 // DetectDeadLanes may mark register uses as undef without removing
532 // them, in which case a non-phi instruction using the original register
533 // may exist in the Endif block even though the register is not live
534 // into it.
535 assert(!O.readsReg());
536 }
537 continue;
538 }
539
540 // Replace uses in Else region
541 if (ElseBlocks.contains(UseBlock))
542 O.setReg(NewReg);
543 }
544
545 // The optimized Reg is not alive through Flow blocks anymore.
546 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
547 OldVarInfo.AliveBlocks.reset(Flow->getNumber());
548
549 updateLiveRangeInElseRegion(Reg, NewReg, Flow, Endif, ElseBlocks);
550 updateLiveRangeInThenRegion(Reg, If, Flow);
551}
552
553void SIOptimizeVGPRLiveRange::optimizeWaterfallLiveRange(
554 Register Reg, MachineBasicBlock *LoopHeader,
555 SmallSetVector<MachineBasicBlock *, 2> &Blocks,
556 SmallVectorImpl<MachineInstr *> &Instructions) const {
557 // Insert a new PHI, marking the value from the last loop iteration undef.
558 LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n');
559 const auto *RC = MRI->getRegClass(Reg);
560 Register NewReg = MRI->createVirtualRegister(RC);
561 Register UndefReg = MRI->createVirtualRegister(RC);
562
563 // Replace all uses in the LOOP region
564 // Use early increment range because setReg() will update the linked list.
565 for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) {
566 auto *UseMI = O.getParent();
567 auto *UseBlock = UseMI->getParent();
568 // Replace uses in Loop blocks
569 if (Blocks.contains(UseBlock))
570 O.setReg(NewReg);
571 }
572
573 MachineInstrBuilder PHI =
574 BuildMI(*LoopHeader, LoopHeader->getFirstNonPHI(), DebugLoc(),
575 TII->get(TargetOpcode::PHI), NewReg);
576 for (auto *Pred : LoopHeader->predecessors()) {
577 if (Blocks.contains(Pred))
578 PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred);
579 else
580 PHI.addReg(Reg).addMBB(Pred);
581 }
582
583 LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg);
584 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
585
586 // Find last use and mark as kill
587 MachineInstr *Kill = nullptr;
588 for (auto *MI : reverse(Instructions)) {
589 if (MI->readsRegister(NewReg, TRI)) {
590 MI->addRegisterKilled(NewReg, TRI);
591 NewVarInfo.Kills.push_back(MI);
592 Kill = MI;
593 break;
594 }
595 }
596 assert(Kill && "Failed to find last usage of register in loop");
597
598 MachineBasicBlock *KillBlock = Kill->getParent();
599 bool PostKillBlock = false;
600 for (auto *Block : Blocks) {
601 auto BBNum = Block->getNumber();
602
603 // collectWaterfallCandidateRegisters only collects registers that are dead
604 // after the loop. So we know that the old reg is no longer live throughout
605 // the waterfall loop.
606 OldVarInfo.AliveBlocks.reset(BBNum);
607
608 // The new register is live up to (and including) the block that kills it.
609 PostKillBlock |= (Block == KillBlock);
610 if (PostKillBlock) {
611 NewVarInfo.AliveBlocks.reset(BBNum);
612 } else if (Block != LoopHeader) {
613 NewVarInfo.AliveBlocks.set(BBNum);
614 }
615 }
616}
617
618char SIOptimizeVGPRLiveRangeLegacy::ID = 0;
619
620INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRangeLegacy, DEBUG_TYPE,
621 "SI Optimize VGPR LiveRange", false, false)
625INITIALIZE_PASS_END(SIOptimizeVGPRLiveRangeLegacy, DEBUG_TYPE,
626 "SI Optimize VGPR LiveRange", false, false)
627
628char &llvm::SIOptimizeVGPRLiveRangeLegacyID = SIOptimizeVGPRLiveRangeLegacy::ID;
629
631 return new SIOptimizeVGPRLiveRangeLegacy();
632}
633
634bool SIOptimizeVGPRLiveRangeLegacy::runOnMachineFunction(MachineFunction &MF) {
635 if (skipFunction(MF.getFunction()))
636 return false;
637
638 LiveVariables *LV = &getAnalysis<LiveVariablesWrapperPass>().getLV();
640 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
641 MachineLoopInfo *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
642 return SIOptimizeVGPRLiveRange(LV, MDT, Loops).run(MF);
643}
644
645PreservedAnalyses
648 MFPropsModifier _(*this, MF);
652
653 bool Changed = SIOptimizeVGPRLiveRange(LV, MDT, Loops).run(MF);
654 if (!Changed)
655 return PreservedAnalyses::all();
656
658 PA.preserve<LiveVariablesAnalysis>();
659 PA.preserveSet<CFGAnalyses>();
660 return PA;
661}
662
663bool SIOptimizeVGPRLiveRange::run(MachineFunction &MF) {
664 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
665 TII = ST.getInstrInfo();
666 TRI = &TII->getRegisterInfo();
667 MRI = &MF.getRegInfo();
668
669 bool MadeChange = false;
670
671 // TODO: we need to think about the order of visiting the blocks to get
672 // optimal result for nesting if-else cases.
673 for (MachineBasicBlock &MBB : MF) {
674 for (auto &MI : MBB.terminators()) {
675 // Detect the if-else blocks
676 if (MI.getOpcode() == AMDGPU::SI_IF) {
677 MachineBasicBlock *IfTarget = MI.getOperand(2).getMBB();
678 auto *Endif = getElseTarget(IfTarget);
679 if (!Endif)
680 continue;
681
682 // Skip unexpected control flow.
683 if (!MDT->dominates(&MBB, IfTarget) || !MDT->dominates(IfTarget, Endif))
684 continue;
685
687 SmallVector<Register> CandidateRegs;
688
689 LLVM_DEBUG(dbgs() << "Checking IF-ELSE-ENDIF: "
690 << printMBBReference(MBB) << ' '
691 << printMBBReference(*IfTarget) << ' '
692 << printMBBReference(*Endif) << '\n');
693
694 // Collect all the blocks in the ELSE region
695 collectElseRegionBlocks(IfTarget, Endif, ElseBlocks);
696
697 // Collect the registers can be optimized
698 collectCandidateRegisters(&MBB, IfTarget, Endif, ElseBlocks,
699 CandidateRegs);
700 MadeChange |= !CandidateRegs.empty();
701 // Now we are safe to optimize.
702 for (auto Reg : CandidateRegs)
703 optimizeLiveRange(Reg, &MBB, IfTarget, Endif, ElseBlocks);
704 } else if (MI.getOpcode() == AMDGPU::SI_WATERFALL_LOOP) {
705 auto *LoopHeader = MI.getOperand(0).getMBB();
706 auto *LoopEnd = &MBB;
707
708 LLVM_DEBUG(dbgs() << "Checking Waterfall loop: "
709 << printMBBReference(*LoopHeader) << '\n');
710
711 SmallSetVector<Register, 16> CandidateRegs;
714
715 collectWaterfallCandidateRegisters(LoopHeader, LoopEnd, CandidateRegs,
716 Blocks, Instructions);
717 MadeChange |= !CandidateRegs.empty();
718 // Now we are safe to optimize.
719 for (auto Reg : CandidateRegs)
720 optimizeWaterfallLiveRange(Reg, LoopHeader, Blocks, Instructions);
721 }
722 }
723 }
724
725 return MadeChange;
726}
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
MachineBasicBlock & MBB
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
Hexagon Hardware Loops
#define _
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
Remove Loads Into Fake Uses
Annotate SI Control Flow
#define LLVM_DEBUG(...)
Definition Debug.h:119
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
LLVM_ABI void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *DefBlock, MachineBasicBlock *BB)
LLVM_ABI void HandleVirtRegUse(Register reg, MachineBasicBlock *MBB, MachineInstr &MI)
LLVM_ABI VarInfo & getVarInfo(Register Reg)
getVarInfo - Return the VarInfo structure for the specified VIRTUAL register.
An RAII based helper class to modify MachineFunctionProperties when running pass.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock * getParent() const
bool isDebugInstr() const
const MachineOperand & getOperand(unsigned i) const
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineBasicBlock * getMBB() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
static use_nodbg_iterator use_nodbg_end()
MachineBasicBlock * getDefBlock(Register Reg) const
Return the machine basic block in which the specified virtual register is defined,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
iterator_range< use_iterator > use_operands(Register Reg) const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void set(unsigned Idx)
bool test(unsigned Idx) const
void reset(unsigned Idx)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Changed
@ BR
Control flow instructions. These all have token chains.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
char & SIOptimizeVGPRLiveRangeLegacyID
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionPass * createSIOptimizeVGPRLiveRangeLegacyPass()
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2192
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
std::vector< MachineInstr * > Kills
Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...
SparseBitVector AliveBlocks
AliveBlocks - Set of blocks in which this value is alive completely through.
LLVM_ABI bool isLiveIn(const MachineBasicBlock &MBB, Register Reg, MachineRegisterInfo &MRI)
isLiveIn - Is Reg live in to MBB?