xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
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 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 
74 #include "AMDGPU.h"
75 #include "GCNSubtarget.h"
76 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
77 #include "SIMachineFunctionInfo.h"
78 #include "llvm/CodeGen/LiveVariables.h"
79 #include "llvm/CodeGen/MachineDominators.h"
80 #include "llvm/CodeGen/MachineLoopInfo.h"
81 #include "llvm/CodeGen/TargetRegisterInfo.h"
82 #include "llvm/InitializePasses.h"
83 
84 using namespace llvm;
85 
86 #define DEBUG_TYPE "si-opt-vgpr-liverange"
87 
88 namespace {
89 
90 class SIOptimizeVGPRLiveRange : public MachineFunctionPass {
91 private:
92   const SIRegisterInfo *TRI = nullptr;
93   const SIInstrInfo *TII = nullptr;
94   LiveVariables *LV = nullptr;
95   MachineDominatorTree *MDT = nullptr;
96   const MachineLoopInfo *Loops = nullptr;
97   MachineRegisterInfo *MRI = nullptr;
98 
99 public:
100   static char ID;
101 
102   MachineBasicBlock *getElseTarget(MachineBasicBlock *MBB) const;
103 
104   void collectElseRegionBlocks(MachineBasicBlock *Flow,
105                                MachineBasicBlock *Endif,
106                                SmallSetVector<MachineBasicBlock *, 16> &) const;
107 
108   void
109   collectCandidateRegisters(MachineBasicBlock *If, MachineBasicBlock *Flow,
110                             MachineBasicBlock *Endif,
111                             SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks,
112                             SmallVectorImpl<Register> &CandidateRegs) const;
113 
114   void collectWaterfallCandidateRegisters(
115       MachineBasicBlock *Loop,
116       SmallSetVector<Register, 16> &CandidateRegs) const;
117 
118   void findNonPHIUsesInBlock(Register Reg, MachineBasicBlock *MBB,
119                              SmallVectorImpl<MachineInstr *> &Uses) const;
120 
121   void updateLiveRangeInThenRegion(Register Reg, MachineBasicBlock *If,
122                                    MachineBasicBlock *Flow) const;
123 
124   void updateLiveRangeInElseRegion(
125       Register Reg, Register NewReg, MachineBasicBlock *Flow,
126       MachineBasicBlock *Endif,
127       SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const;
128 
129   void
130   optimizeLiveRange(Register Reg, MachineBasicBlock *If,
131                     MachineBasicBlock *Flow, MachineBasicBlock *Endif,
132                     SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const;
133 
134   void optimizeWaterfallLiveRange(Register Reg, MachineBasicBlock *If) const;
135 
136   SIOptimizeVGPRLiveRange() : MachineFunctionPass(ID) {}
137 
138   bool runOnMachineFunction(MachineFunction &MF) override;
139 
140   StringRef getPassName() const override {
141     return "SI Optimize VGPR LiveRange";
142   }
143 
144   void getAnalysisUsage(AnalysisUsage &AU) const override {
145     AU.addRequired<LiveVariables>();
146     AU.addRequired<MachineDominatorTree>();
147     AU.addRequired<MachineLoopInfo>();
148     AU.addPreserved<LiveVariables>();
149     AU.addPreserved<MachineDominatorTree>();
150     AU.addPreserved<MachineLoopInfo>();
151     MachineFunctionPass::getAnalysisUsage(AU);
152   }
153 
154   MachineFunctionProperties getRequiredProperties() const override {
155     return MachineFunctionProperties().set(
156         MachineFunctionProperties::Property::IsSSA);
157   }
158 
159   MachineFunctionProperties getClearedProperties() const override {
160     return MachineFunctionProperties().set(
161         MachineFunctionProperties::Property::NoPHIs);
162   }
163 };
164 
165 } // end anonymous namespace
166 
167 // Check whether the MBB is a else flow block and get the branching target which
168 // is the Endif block
169 MachineBasicBlock *
170 SIOptimizeVGPRLiveRange::getElseTarget(MachineBasicBlock *MBB) const {
171   for (auto &BR : MBB->terminators()) {
172     if (BR.getOpcode() == AMDGPU::SI_ELSE)
173       return BR.getOperand(2).getMBB();
174   }
175   return nullptr;
176 }
177 
178 void SIOptimizeVGPRLiveRange::collectElseRegionBlocks(
179     MachineBasicBlock *Flow, MachineBasicBlock *Endif,
180     SmallSetVector<MachineBasicBlock *, 16> &Blocks) const {
181   assert(Flow != Endif);
182 
183   MachineBasicBlock *MBB = Endif;
184   unsigned Cur = 0;
185   while (MBB) {
186     for (auto *Pred : MBB->predecessors()) {
187       if (Pred != Flow && !Blocks.contains(Pred))
188         Blocks.insert(Pred);
189     }
190 
191     if (Cur < Blocks.size())
192       MBB = Blocks[Cur++];
193     else
194       MBB = nullptr;
195   }
196 
197   LLVM_DEBUG({
198     dbgs() << "Found Else blocks: ";
199     for (auto *MBB : Blocks)
200       dbgs() << printMBBReference(*MBB) << ' ';
201     dbgs() << '\n';
202   });
203 }
204 
205 /// Find the instructions(excluding phi) in \p MBB that uses the \p Reg.
206 void SIOptimizeVGPRLiveRange::findNonPHIUsesInBlock(
207     Register Reg, MachineBasicBlock *MBB,
208     SmallVectorImpl<MachineInstr *> &Uses) const {
209   for (auto &UseMI : MRI->use_nodbg_instructions(Reg)) {
210     if (UseMI.getParent() == MBB && !UseMI.isPHI())
211       Uses.push_back(&UseMI);
212   }
213 }
214 
215 /// Collect the killed registers in the ELSE region which are not alive through
216 /// the whole THEN region.
217 void SIOptimizeVGPRLiveRange::collectCandidateRegisters(
218     MachineBasicBlock *If, MachineBasicBlock *Flow, MachineBasicBlock *Endif,
219     SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks,
220     SmallVectorImpl<Register> &CandidateRegs) const {
221 
222   SmallSet<Register, 8> KillsInElse;
223 
224   for (auto *Else : ElseBlocks) {
225     for (auto &MI : Else->instrs()) {
226       if (MI.isDebugInstr())
227         continue;
228 
229       for (auto &MO : MI.operands()) {
230         if (!MO.isReg() || !MO.getReg() || MO.isDef())
231           continue;
232 
233         Register MOReg = MO.getReg();
234         // We can only optimize AGPR/VGPR virtual register
235         if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg))
236           continue;
237 
238         if (MO.readsReg()) {
239           LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg);
240           const MachineBasicBlock *DefMBB = MRI->getVRegDef(MOReg)->getParent();
241           // Make sure two conditions are met:
242           // a.) the value is defined before/in the IF block
243           // b.) should be defined in the same loop-level.
244           if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) &&
245               Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If)) {
246             // Check if the register is live into the endif block. If not,
247             // consider it killed in the else region.
248             LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg);
249             if (!VI.isLiveIn(*Endif, MOReg, *MRI)) {
250               KillsInElse.insert(MOReg);
251             } else {
252               LLVM_DEBUG(dbgs() << "Excluding " << printReg(MOReg, TRI)
253                                 << " as Live in Endif\n");
254             }
255           }
256         }
257       }
258     }
259   }
260 
261   // Check the phis in the Endif, looking for value coming from the ELSE
262   // region. Make sure the phi-use is the last use.
263   for (auto &MI : Endif->phis()) {
264     for (unsigned Idx = 1; Idx < MI.getNumOperands(); Idx += 2) {
265       auto &MO = MI.getOperand(Idx);
266       auto *Pred = MI.getOperand(Idx + 1).getMBB();
267       if (Pred == Flow)
268         continue;
269       assert(ElseBlocks.contains(Pred) && "Should be from Else region\n");
270 
271       if (!MO.isReg() || !MO.getReg() || MO.isUndef())
272         continue;
273 
274       Register Reg = MO.getReg();
275       if (Reg.isPhysical() || !TRI->isVectorRegister(*MRI, Reg))
276         continue;
277 
278       LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
279 
280       if (VI.isLiveIn(*Endif, Reg, *MRI)) {
281         LLVM_DEBUG(dbgs() << "Excluding " << printReg(Reg, TRI)
282                           << " as Live in Endif\n");
283         continue;
284       }
285       // Make sure two conditions are met:
286       // a.) the value is defined before/in the IF block
287       // b.) should be defined in the same loop-level.
288       const MachineBasicBlock *DefMBB = MRI->getVRegDef(Reg)->getParent();
289       if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) &&
290           Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If))
291         KillsInElse.insert(Reg);
292     }
293   }
294 
295   auto IsLiveThroughThen = [&](Register Reg) {
296     for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E;
297          ++I) {
298       if (!I->readsReg())
299         continue;
300       auto *UseMI = I->getParent();
301       auto *UseMBB = UseMI->getParent();
302       if (UseMBB == Flow || UseMBB == Endif) {
303         if (!UseMI->isPHI())
304           return true;
305 
306         auto *IncomingMBB = UseMI->getOperand(I.getOperandNo() + 1).getMBB();
307         // The register is live through the path If->Flow or Flow->Endif.
308         // we should not optimize for such cases.
309         if ((UseMBB == Flow && IncomingMBB != If) ||
310             (UseMBB == Endif && IncomingMBB == Flow))
311           return true;
312       }
313     }
314     return false;
315   };
316 
317   for (auto Reg : KillsInElse) {
318     if (!IsLiveThroughThen(Reg))
319       CandidateRegs.push_back(Reg);
320   }
321 }
322 
323 /// Collect the registers used in the waterfall loop block that are defined
324 /// before.
325 void SIOptimizeVGPRLiveRange::collectWaterfallCandidateRegisters(
326     MachineBasicBlock *Loop,
327     SmallSetVector<Register, 16> &CandidateRegs) const {
328 
329   for (auto &MI : Loop->instrs()) {
330     if (MI.isDebugInstr())
331       continue;
332 
333     for (auto &MO : MI.operands()) {
334       if (!MO.isReg() || !MO.getReg() || MO.isDef())
335         continue;
336 
337       Register MOReg = MO.getReg();
338       // We can only optimize AGPR/VGPR virtual register
339       if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg))
340         continue;
341 
342       if (MO.readsReg()) {
343         const MachineBasicBlock *DefMBB = MRI->getVRegDef(MOReg)->getParent();
344         // Make sure the value is defined before the LOOP block
345         if (DefMBB != Loop && !CandidateRegs.contains(MOReg)) {
346           // If the variable is used after the loop, the register coalescer will
347           // merge the newly created register and remove the phi node again.
348           // Just do nothing in that case.
349           LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(MOReg);
350           bool IsUsed = false;
351           for (auto *Succ : Loop->successors()) {
352             if (Succ != Loop && OldVarInfo.isLiveIn(*Succ, MOReg, *MRI)) {
353               IsUsed = true;
354               break;
355             }
356           }
357           if (!IsUsed) {
358             LLVM_DEBUG(dbgs() << "Found candidate reg: "
359                               << printReg(MOReg, TRI, 0, MRI) << '\n');
360             CandidateRegs.insert(MOReg);
361           } else {
362             LLVM_DEBUG(dbgs() << "Reg is used after loop, ignoring: "
363                               << printReg(MOReg, TRI, 0, MRI) << '\n');
364           }
365         }
366       }
367     }
368   }
369 }
370 
371 // Re-calculate the liveness of \p Reg in the THEN-region
372 void SIOptimizeVGPRLiveRange::updateLiveRangeInThenRegion(
373     Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow) const {
374   SetVector<MachineBasicBlock *> Blocks;
375   SmallVector<MachineBasicBlock *> WorkList({If});
376 
377   // Collect all successors until we see the flow block, where we should
378   // reconverge.
379   while (!WorkList.empty()) {
380     auto *MBB = WorkList.pop_back_val();
381     for (auto *Succ : MBB->successors()) {
382       if (Succ != Flow && !Blocks.contains(Succ)) {
383         WorkList.push_back(Succ);
384         Blocks.insert(Succ);
385       }
386     }
387   }
388 
389   LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
390   for (MachineBasicBlock *MBB : Blocks) {
391     // Clear Live bit, as we will recalculate afterwards
392     LLVM_DEBUG(dbgs() << "Clear AliveBlock " << printMBBReference(*MBB)
393                       << '\n');
394     OldVarInfo.AliveBlocks.reset(MBB->getNumber());
395   }
396 
397   SmallPtrSet<MachineBasicBlock *, 4> PHIIncoming;
398 
399   // Get the blocks the Reg should be alive through
400   for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E;
401        ++I) {
402     auto *UseMI = I->getParent();
403     if (UseMI->isPHI() && I->readsReg()) {
404       if (Blocks.contains(UseMI->getParent()))
405         PHIIncoming.insert(UseMI->getOperand(I.getOperandNo() + 1).getMBB());
406     }
407   }
408 
409   for (MachineBasicBlock *MBB : Blocks) {
410     SmallVector<MachineInstr *> Uses;
411     // PHI instructions has been processed before.
412     findNonPHIUsesInBlock(Reg, MBB, Uses);
413 
414     if (Uses.size() == 1) {
415       LLVM_DEBUG(dbgs() << "Found one Non-PHI use in "
416                         << printMBBReference(*MBB) << '\n');
417       LV->HandleVirtRegUse(Reg, MBB, *(*Uses.begin()));
418     } else if (Uses.size() > 1) {
419       // Process the instructions in-order
420       LLVM_DEBUG(dbgs() << "Found " << Uses.size() << " Non-PHI uses in "
421                         << printMBBReference(*MBB) << '\n');
422       for (MachineInstr &MI : *MBB) {
423         if (llvm::is_contained(Uses, &MI))
424           LV->HandleVirtRegUse(Reg, MBB, MI);
425       }
426     }
427 
428     // Mark Reg alive through the block if this is a PHI incoming block
429     if (PHIIncoming.contains(MBB))
430       LV->MarkVirtRegAliveInBlock(OldVarInfo, MRI->getVRegDef(Reg)->getParent(),
431                                   MBB);
432   }
433 
434   // Set the isKilled flag if we get new Kills in the THEN region.
435   for (auto *MI : OldVarInfo.Kills) {
436     if (Blocks.contains(MI->getParent()))
437       MI->addRegisterKilled(Reg, TRI);
438   }
439 }
440 
441 void SIOptimizeVGPRLiveRange::updateLiveRangeInElseRegion(
442     Register Reg, Register NewReg, MachineBasicBlock *Flow,
443     MachineBasicBlock *Endif,
444     SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const {
445   LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg);
446   LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
447 
448   // Transfer aliveBlocks from Reg to NewReg
449   for (auto *MBB : ElseBlocks) {
450     unsigned BBNum = MBB->getNumber();
451     if (OldVarInfo.AliveBlocks.test(BBNum)) {
452       NewVarInfo.AliveBlocks.set(BBNum);
453       LLVM_DEBUG(dbgs() << "Removing AliveBlock " << printMBBReference(*MBB)
454                         << '\n');
455       OldVarInfo.AliveBlocks.reset(BBNum);
456     }
457   }
458 
459   // Transfer the possible Kills in ElseBlocks from Reg to NewReg
460   auto I = OldVarInfo.Kills.begin();
461   while (I != OldVarInfo.Kills.end()) {
462     if (ElseBlocks.contains((*I)->getParent())) {
463       NewVarInfo.Kills.push_back(*I);
464       I = OldVarInfo.Kills.erase(I);
465     } else {
466       ++I;
467     }
468   }
469 }
470 
471 void SIOptimizeVGPRLiveRange::optimizeLiveRange(
472     Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow,
473     MachineBasicBlock *Endif,
474     SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const {
475   // Insert a new PHI, marking the value from the THEN region being
476   // undef.
477   LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n');
478   const auto *RC = MRI->getRegClass(Reg);
479   Register NewReg = MRI->createVirtualRegister(RC);
480   Register UndefReg = MRI->createVirtualRegister(RC);
481   MachineInstrBuilder PHI = BuildMI(*Flow, Flow->getFirstNonPHI(), DebugLoc(),
482                                     TII->get(TargetOpcode::PHI), NewReg);
483   for (auto *Pred : Flow->predecessors()) {
484     if (Pred == If)
485       PHI.addReg(Reg).addMBB(Pred);
486     else
487       PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred);
488   }
489 
490   // Replace all uses in the ELSE region or the PHIs in ENDIF block
491   // Use early increment range because setReg() will update the linked list.
492   for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) {
493     auto *UseMI = O.getParent();
494     auto *UseBlock = UseMI->getParent();
495     // Replace uses in Endif block
496     if (UseBlock == Endif) {
497       assert(UseMI->isPHI() && "Uses should be PHI in Endif block");
498       O.setReg(NewReg);
499       continue;
500     }
501 
502     // Replace uses in Else region
503     if (ElseBlocks.contains(UseBlock))
504       O.setReg(NewReg);
505   }
506 
507   // The optimized Reg is not alive through Flow blocks anymore.
508   LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
509   OldVarInfo.AliveBlocks.reset(Flow->getNumber());
510 
511   updateLiveRangeInElseRegion(Reg, NewReg, Flow, Endif, ElseBlocks);
512   updateLiveRangeInThenRegion(Reg, If, Flow);
513 }
514 
515 void SIOptimizeVGPRLiveRange::optimizeWaterfallLiveRange(
516     Register Reg, MachineBasicBlock *Loop) const {
517   // Insert a new PHI, marking the value from the last loop iteration undef.
518   LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n');
519   const auto *RC = MRI->getRegClass(Reg);
520   Register NewReg = MRI->createVirtualRegister(RC);
521   Register UndefReg = MRI->createVirtualRegister(RC);
522 
523   // Replace all uses in the LOOP region
524   // Use early increment range because setReg() will update the linked list.
525   for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) {
526     auto *UseMI = O.getParent();
527     auto *UseBlock = UseMI->getParent();
528     // Replace uses in Loop block
529     if (UseBlock == Loop)
530       O.setReg(NewReg);
531   }
532 
533   MachineInstrBuilder PHI = BuildMI(*Loop, Loop->getFirstNonPHI(), DebugLoc(),
534                                     TII->get(TargetOpcode::PHI), NewReg);
535   for (auto *Pred : Loop->predecessors()) {
536     if (Pred == Loop)
537       PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred);
538     else
539       PHI.addReg(Reg).addMBB(Pred);
540   }
541 
542   LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg);
543   LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
544 
545   // collectWaterfallCandidateRegisters only collects registers that are dead
546   // after the loop. So we know that the old reg is not live throughout the
547   // whole block anymore.
548   OldVarInfo.AliveBlocks.reset(Loop->getNumber());
549 
550   // Mark the last use as kill
551   for (auto &MI : reverse(Loop->instrs())) {
552     if (MI.readsRegister(NewReg, TRI)) {
553       MI.addRegisterKilled(NewReg, TRI);
554       NewVarInfo.Kills.push_back(&MI);
555       break;
556     }
557   }
558   assert(!NewVarInfo.Kills.empty() &&
559          "Failed to find last usage of register in loop");
560 }
561 
562 char SIOptimizeVGPRLiveRange::ID = 0;
563 
564 INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRange, DEBUG_TYPE,
565                       "SI Optimize VGPR LiveRange", false, false)
566 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
567 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
568 INITIALIZE_PASS_DEPENDENCY(LiveVariables)
569 INITIALIZE_PASS_END(SIOptimizeVGPRLiveRange, DEBUG_TYPE,
570                     "SI Optimize VGPR LiveRange", false, false)
571 
572 char &llvm::SIOptimizeVGPRLiveRangeID = SIOptimizeVGPRLiveRange::ID;
573 
574 FunctionPass *llvm::createSIOptimizeVGPRLiveRangePass() {
575   return new SIOptimizeVGPRLiveRange();
576 }
577 
578 bool SIOptimizeVGPRLiveRange::runOnMachineFunction(MachineFunction &MF) {
579 
580   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
581   TII = ST.getInstrInfo();
582   TRI = &TII->getRegisterInfo();
583   MDT = &getAnalysis<MachineDominatorTree>();
584   Loops = &getAnalysis<MachineLoopInfo>();
585   LV = &getAnalysis<LiveVariables>();
586   MRI = &MF.getRegInfo();
587 
588   if (skipFunction(MF.getFunction()))
589     return false;
590 
591   bool MadeChange = false;
592 
593   // TODO: we need to think about the order of visiting the blocks to get
594   // optimal result for nesting if-else cases.
595   for (MachineBasicBlock &MBB : MF) {
596     for (auto &MI : MBB.terminators()) {
597       // Detect the if-else blocks
598       if (MI.getOpcode() == AMDGPU::SI_IF) {
599         MachineBasicBlock *IfTarget = MI.getOperand(2).getMBB();
600         auto *Endif = getElseTarget(IfTarget);
601         if (!Endif)
602           continue;
603 
604         SmallSetVector<MachineBasicBlock *, 16> ElseBlocks;
605         SmallVector<Register> CandidateRegs;
606 
607         LLVM_DEBUG(dbgs() << "Checking IF-ELSE-ENDIF: "
608                           << printMBBReference(MBB) << ' '
609                           << printMBBReference(*IfTarget) << ' '
610                           << printMBBReference(*Endif) << '\n');
611 
612         // Collect all the blocks in the ELSE region
613         collectElseRegionBlocks(IfTarget, Endif, ElseBlocks);
614 
615         // Collect the registers can be optimized
616         collectCandidateRegisters(&MBB, IfTarget, Endif, ElseBlocks,
617                                   CandidateRegs);
618         MadeChange |= !CandidateRegs.empty();
619         // Now we are safe to optimize.
620         for (auto Reg : CandidateRegs)
621           optimizeLiveRange(Reg, &MBB, IfTarget, Endif, ElseBlocks);
622       } else if (MI.getOpcode() == AMDGPU::SI_WATERFALL_LOOP) {
623         LLVM_DEBUG(dbgs() << "Checking Waterfall loop: "
624                           << printMBBReference(MBB) << '\n');
625 
626         SmallSetVector<Register, 16> CandidateRegs;
627         collectWaterfallCandidateRegisters(&MBB, CandidateRegs);
628         MadeChange |= !CandidateRegs.empty();
629         // Now we are safe to optimize.
630         for (auto Reg : CandidateRegs)
631           optimizeWaterfallLiveRange(Reg, &MBB);
632       }
633     }
634   }
635 
636   return MadeChange;
637 }
638