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"
84#include "llvm/IR/Dominators.h"
86
87using namespace llvm;
88
89#define DEBUG_TYPE "si-opt-vgpr-liverange"
90
91namespace {
92
93class SIOptimizeVGPRLiveRange {
94private:
95 const SIRegisterInfo *TRI = nullptr;
96 const SIInstrInfo *TII = nullptr;
97 LiveVariables *LV = nullptr;
98 MachineDominatorTree *MDT = nullptr;
99 const MachineLoopInfo *Loops = nullptr;
100 MachineRegisterInfo *MRI = nullptr;
101
102public:
103 SIOptimizeVGPRLiveRange(LiveVariables *LV, MachineDominatorTree *MDT,
105 : LV(LV), MDT(MDT), Loops(Loops) {}
106 bool run(MachineFunction &MF);
107
108 MachineBasicBlock *getElseTarget(MachineBasicBlock *MBB) const;
109
110 void collectElseRegionBlocks(MachineBasicBlock *Flow,
111 MachineBasicBlock *Endif,
113
114 void
115 collectCandidateRegisters(MachineBasicBlock *If, MachineBasicBlock *Flow,
116 MachineBasicBlock *Endif,
118 SmallVectorImpl<Register> &CandidateRegs) const;
119
120 void collectWaterfallCandidateRegisters(
121 MachineBasicBlock *LoopHeader, MachineBasicBlock *LoopEnd,
122 SmallSetVector<Register, 16> &CandidateRegs,
124 SmallVectorImpl<MachineInstr *> &Instructions) const;
125
126 void findNonPHIUsesInBlock(Register Reg, MachineBasicBlock *MBB,
128
129 void updateLiveRangeInThenRegion(Register Reg, MachineBasicBlock *If,
130 MachineBasicBlock *Flow) const;
131
132 void updateLiveRangeInElseRegion(
134 MachineBasicBlock *Endif,
136
137 void
138 optimizeLiveRange(Register Reg, MachineBasicBlock *If,
141
142 void optimizeWaterfallLiveRange(
143 Register Reg, MachineBasicBlock *LoopHeader,
145 SmallVectorImpl<MachineInstr *> &Instructions) const;
146};
147
148class SIOptimizeVGPRLiveRangeLegacy : public MachineFunctionPass {
149public:
150 static char ID;
151
152 SIOptimizeVGPRLiveRangeLegacy() : MachineFunctionPass(ID) {}
153
154 bool runOnMachineFunction(MachineFunction &MF) override;
155
156 StringRef getPassName() const override {
157 return "SI Optimize VGPR LiveRange";
158 }
159
160 void getAnalysisUsage(AnalysisUsage &AU) const override {
161 AU.setPreservesCFG();
170 }
171
172 MachineFunctionProperties getRequiredProperties() const override {
173 return MachineFunctionProperties().setIsSSA();
174 }
175
176 MachineFunctionProperties getClearedProperties() const override {
177 return MachineFunctionProperties().setNoPHIs();
178 }
179};
180
181} // end anonymous namespace
182
183// Check whether the MBB is a else flow block and get the branching target which
184// is the Endif block
186SIOptimizeVGPRLiveRange::getElseTarget(MachineBasicBlock *MBB) const {
187 for (auto &BR : MBB->terminators()) {
188 if (BR.getOpcode() == AMDGPU::SI_ELSE)
189 return BR.getOperand(2).getMBB();
190 }
191 return nullptr;
192}
193
194void SIOptimizeVGPRLiveRange::collectElseRegionBlocks(
195 MachineBasicBlock *Flow, MachineBasicBlock *Endif,
196 SmallSetVector<MachineBasicBlock *, 16> &Blocks) const {
197 assert(Flow != Endif);
198
199 MachineBasicBlock *MBB = Endif;
200 unsigned Cur = 0;
201 while (MBB) {
202 for (auto *Pred : MBB->predecessors()) {
203 if (Pred != Flow)
204 Blocks.insert(Pred);
205 }
206
207 if (Cur < Blocks.size())
208 MBB = Blocks[Cur++];
209 else
210 MBB = nullptr;
211 }
212
213 LLVM_DEBUG({
214 dbgs() << "Found Else blocks: ";
215 for (auto *MBB : Blocks)
216 dbgs() << printMBBReference(*MBB) << ' ';
217 dbgs() << '\n';
218 });
219}
220
221/// Find the instructions(excluding phi) in \p MBB that uses the \p Reg.
222void SIOptimizeVGPRLiveRange::findNonPHIUsesInBlock(
223 Register Reg, MachineBasicBlock *MBB,
224 SmallVectorImpl<MachineInstr *> &Uses) const {
225 for (auto &UseMI : MRI->use_nodbg_instructions(Reg)) {
226 if (UseMI.getParent() == MBB && !UseMI.isPHI())
227 Uses.push_back(&UseMI);
228 }
229}
230
231/// Collect the killed registers in the ELSE region which are not alive through
232/// the whole THEN region.
233void SIOptimizeVGPRLiveRange::collectCandidateRegisters(
234 MachineBasicBlock *If, MachineBasicBlock *Flow, MachineBasicBlock *Endif,
235 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks,
236 SmallVectorImpl<Register> &CandidateRegs) const {
237
238 SmallSet<Register, 8> KillsInElse;
239
240 for (auto *Else : ElseBlocks) {
241 for (auto &MI : Else->instrs()) {
242 if (MI.isDebugInstr())
243 continue;
244
245 for (auto &MO : MI.operands()) {
246 if (!MO.isReg() || !MO.getReg() || MO.isDef())
247 continue;
248
249 Register MOReg = MO.getReg();
250 // We can only optimize AGPR/VGPR virtual register
251 if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg))
252 continue;
253
254 if (MO.readsReg()) {
255 LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg);
256 const MachineBasicBlock *DefMBB = MRI->getVRegDef(MOReg)->getParent();
257 // Make sure two conditions are met:
258 // a.) the value is defined before/in the IF block
259 // b.) should be defined in the same loop-level.
260 if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) &&
261 Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If)) {
262 // Check if the register is live into the endif block. If not,
263 // consider it killed in the else region.
264 LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg);
265 if (!VI.isLiveIn(*Endif, MOReg, *MRI)) {
266 KillsInElse.insert(MOReg);
267 } else {
268 LLVM_DEBUG(dbgs() << "Excluding " << printReg(MOReg, TRI)
269 << " as Live in Endif\n");
270 }
271 }
272 }
273 }
274 }
275 }
276
277 // Check the phis in the Endif, looking for value coming from the ELSE
278 // region. Make sure the phi-use is the last use.
279 for (auto &MI : Endif->phis()) {
280 for (unsigned Idx = 1; Idx < MI.getNumOperands(); Idx += 2) {
281 auto &MO = MI.getOperand(Idx);
282 auto *Pred = MI.getOperand(Idx + 1).getMBB();
283 if (Pred == Flow)
284 continue;
285 assert(ElseBlocks.contains(Pred) && "Should be from Else region\n");
286
287 if (!MO.isReg() || !MO.getReg() || MO.isUndef())
288 continue;
289
290 Register Reg = MO.getReg();
291 if (Reg.isPhysical() || !TRI->isVectorRegister(*MRI, Reg))
292 continue;
293
294 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
295
296 if (VI.isLiveIn(*Endif, Reg, *MRI)) {
297 LLVM_DEBUG(dbgs() << "Excluding " << printReg(Reg, TRI)
298 << " as Live in Endif\n");
299 continue;
300 }
301 // Make sure two conditions are met:
302 // a.) the value is defined before/in the IF block
303 // b.) should be defined in the same loop-level.
304 const MachineBasicBlock *DefMBB = MRI->getVRegDef(Reg)->getParent();
305 if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) &&
306 Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If))
307 KillsInElse.insert(Reg);
308 }
309 }
310
311 auto IsLiveThroughThen = [&](Register Reg) {
312 for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E;
313 ++I) {
314 if (!I->readsReg())
315 continue;
316 auto *UseMI = I->getParent();
317 auto *UseMBB = UseMI->getParent();
318 if (UseMBB == Flow || UseMBB == Endif) {
319 if (!UseMI->isPHI())
320 return true;
321
322 auto *IncomingMBB = UseMI->getOperand(I.getOperandNo() + 1).getMBB();
323 // The register is live through the path If->Flow or Flow->Endif.
324 // we should not optimize for such cases.
325 if ((UseMBB == Flow && IncomingMBB != If) ||
326 (UseMBB == Endif && IncomingMBB == Flow))
327 return true;
328 }
329 }
330 return false;
331 };
332
333 for (auto Reg : KillsInElse) {
334 if (!IsLiveThroughThen(Reg))
335 CandidateRegs.push_back(Reg);
336 }
337}
338
339/// Collect the registers used in the waterfall loop block that are defined
340/// before.
341void SIOptimizeVGPRLiveRange::collectWaterfallCandidateRegisters(
342 MachineBasicBlock *LoopHeader, MachineBasicBlock *LoopEnd,
343 SmallSetVector<Register, 16> &CandidateRegs,
344 SmallSetVector<MachineBasicBlock *, 2> &Blocks,
345 SmallVectorImpl<MachineInstr *> &Instructions) const {
346
347 // Collect loop instructions, potentially spanning multiple blocks
348 auto *MBB = LoopHeader;
349 for (;;) {
350 Blocks.insert(MBB);
351 for (auto &MI : *MBB) {
352 if (MI.isDebugInstr())
353 continue;
354 Instructions.push_back(&MI);
355 }
356 if (MBB == LoopEnd)
357 break;
358
359 if ((MBB != LoopHeader && MBB->pred_size() != 1) ||
360 (MBB == LoopHeader && MBB->pred_size() != 2) || MBB->succ_size() != 1) {
361 LLVM_DEBUG(dbgs() << "Unexpected edges in CFG, ignoring loop\n");
362 return;
363 }
364
365 MBB = *MBB->succ_begin();
366 }
367
368 for (auto *I : Instructions) {
369 auto &MI = *I;
370
371 for (auto &MO : MI.all_uses()) {
372 if (!MO.getReg())
373 continue;
374
375 Register MOReg = MO.getReg();
376 // We can only optimize AGPR/VGPR virtual register
377 if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg))
378 continue;
379
380 if (MO.readsReg()) {
381 MachineBasicBlock *DefMBB = MRI->getVRegDef(MOReg)->getParent();
382 // Make sure the value is defined before the LOOP block
383 if (!Blocks.contains(DefMBB) && !CandidateRegs.contains(MOReg)) {
384 // If the variable is used after the loop, the register coalescer will
385 // merge the newly created register and remove the phi node again.
386 // Just do nothing in that case.
387 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(MOReg);
388 bool IsUsed = false;
389 for (auto *Succ : LoopEnd->successors()) {
390 if (!Blocks.contains(Succ) &&
391 OldVarInfo.isLiveIn(*Succ, MOReg, *MRI)) {
392 IsUsed = true;
393 break;
394 }
395 }
396 if (!IsUsed) {
397 LLVM_DEBUG(dbgs() << "Found candidate reg: "
398 << printReg(MOReg, TRI, 0, MRI) << '\n');
399 CandidateRegs.insert(MOReg);
400 } else {
401 LLVM_DEBUG(dbgs() << "Reg is used after loop, ignoring: "
402 << printReg(MOReg, TRI, 0, MRI) << '\n');
403 }
404 }
405 }
406 }
407 }
408}
409
410// Re-calculate the liveness of \p Reg in the THEN-region
411void SIOptimizeVGPRLiveRange::updateLiveRangeInThenRegion(
412 Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow) const {
413 SetVector<MachineBasicBlock *> Blocks;
415
416 // Collect all successors until we see the flow block, where we should
417 // reconverge.
418 while (!WorkList.empty()) {
419 auto *MBB = WorkList.pop_back_val();
420 for (auto *Succ : MBB->successors()) {
421 if (Succ != Flow && Blocks.insert(Succ))
422 WorkList.push_back(Succ);
423 }
424 }
425
426 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
427 for (MachineBasicBlock *MBB : Blocks) {
428 // Clear Live bit, as we will recalculate afterwards
429 LLVM_DEBUG(dbgs() << "Clear AliveBlock " << printMBBReference(*MBB)
430 << '\n');
431 OldVarInfo.AliveBlocks.reset(MBB->getNumber());
432 }
433
434 SmallPtrSet<MachineBasicBlock *, 4> PHIIncoming;
435
436 // Get the blocks the Reg should be alive through
437 for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E;
438 ++I) {
439 auto *UseMI = I->getParent();
440 if (UseMI->isPHI() && I->readsReg()) {
441 if (Blocks.contains(UseMI->getParent()))
442 PHIIncoming.insert(UseMI->getOperand(I.getOperandNo() + 1).getMBB());
443 }
444 }
445
446 for (MachineBasicBlock *MBB : Blocks) {
448 // PHI instructions has been processed before.
449 findNonPHIUsesInBlock(Reg, MBB, Uses);
450
451 if (Uses.size() == 1) {
452 LLVM_DEBUG(dbgs() << "Found one Non-PHI use in "
453 << printMBBReference(*MBB) << '\n');
454 LV->HandleVirtRegUse(Reg, MBB, *(*Uses.begin()));
455 } else if (Uses.size() > 1) {
456 // Process the instructions in-order
457 LLVM_DEBUG(dbgs() << "Found " << Uses.size() << " Non-PHI uses in "
458 << printMBBReference(*MBB) << '\n');
459 for (MachineInstr &MI : *MBB) {
461 LV->HandleVirtRegUse(Reg, MBB, MI);
462 }
463 }
464
465 // Mark Reg alive through the block if this is a PHI incoming block
466 if (PHIIncoming.contains(MBB))
467 LV->MarkVirtRegAliveInBlock(OldVarInfo, MRI->getVRegDef(Reg)->getParent(),
468 MBB);
469 }
470
471 // Set the isKilled flag if we get new Kills in the THEN region.
472 for (auto *MI : OldVarInfo.Kills) {
473 if (Blocks.contains(MI->getParent()))
474 MI->addRegisterKilled(Reg, TRI);
475 }
476}
477
478void SIOptimizeVGPRLiveRange::updateLiveRangeInElseRegion(
479 Register Reg, Register NewReg, MachineBasicBlock *Flow,
480 MachineBasicBlock *Endif,
481 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const {
482 LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg);
483 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
484
485 // Transfer aliveBlocks from Reg to NewReg
486 for (auto *MBB : ElseBlocks) {
487 unsigned BBNum = MBB->getNumber();
488 if (OldVarInfo.AliveBlocks.test(BBNum)) {
489 NewVarInfo.AliveBlocks.set(BBNum);
490 LLVM_DEBUG(dbgs() << "Removing AliveBlock " << printMBBReference(*MBB)
491 << '\n');
492 OldVarInfo.AliveBlocks.reset(BBNum);
493 }
494 }
495
496 // Transfer the possible Kills in ElseBlocks from Reg to NewReg
497 llvm::erase_if(OldVarInfo.Kills, [&](MachineInstr *MI) {
498 if (!ElseBlocks.contains(MI->getParent()))
499 return false;
500 NewVarInfo.Kills.push_back(MI);
501 return true;
502 });
503}
504
505void SIOptimizeVGPRLiveRange::optimizeLiveRange(
506 Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow,
507 MachineBasicBlock *Endif,
508 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const {
509 // Insert a new PHI, marking the value from the THEN region being
510 // undef.
511 LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n');
512 const auto *RC = MRI->getRegClass(Reg);
513 Register NewReg = MRI->createVirtualRegister(RC);
514 Register UndefReg = MRI->createVirtualRegister(RC);
515 MachineInstrBuilder PHI = BuildMI(*Flow, Flow->getFirstNonPHI(), DebugLoc(),
516 TII->get(TargetOpcode::PHI), NewReg);
517 for (auto *Pred : Flow->predecessors()) {
518 if (Pred == If)
519 PHI.addReg(Reg).addMBB(Pred);
520 else
521 PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred);
522 }
523
524 // Replace all uses in the ELSE region or the PHIs in ENDIF block
525 // Use early increment range because setReg() will update the linked list.
526 for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) {
527 auto *UseMI = O.getParent();
528 auto *UseBlock = UseMI->getParent();
529 // Replace uses in Endif block
530 if (UseBlock == Endif) {
531 if (UseMI->isPHI())
532 O.setReg(NewReg);
533 else if (UseMI->isDebugInstr())
534 continue;
535 else {
536 // DetectDeadLanes may mark register uses as undef without removing
537 // them, in which case a non-phi instruction using the original register
538 // may exist in the Endif block even though the register is not live
539 // into it.
540 assert(!O.readsReg());
541 }
542 continue;
543 }
544
545 // Replace uses in Else region
546 if (ElseBlocks.contains(UseBlock))
547 O.setReg(NewReg);
548 }
549
550 // The optimized Reg is not alive through Flow blocks anymore.
551 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
552 OldVarInfo.AliveBlocks.reset(Flow->getNumber());
553
554 updateLiveRangeInElseRegion(Reg, NewReg, Flow, Endif, ElseBlocks);
555 updateLiveRangeInThenRegion(Reg, If, Flow);
556}
557
558void SIOptimizeVGPRLiveRange::optimizeWaterfallLiveRange(
559 Register Reg, MachineBasicBlock *LoopHeader,
560 SmallSetVector<MachineBasicBlock *, 2> &Blocks,
561 SmallVectorImpl<MachineInstr *> &Instructions) const {
562 // Insert a new PHI, marking the value from the last loop iteration undef.
563 LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n');
564 const auto *RC = MRI->getRegClass(Reg);
565 Register NewReg = MRI->createVirtualRegister(RC);
566 Register UndefReg = MRI->createVirtualRegister(RC);
567
568 // Replace all uses in the LOOP region
569 // Use early increment range because setReg() will update the linked list.
570 for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) {
571 auto *UseMI = O.getParent();
572 auto *UseBlock = UseMI->getParent();
573 // Replace uses in Loop blocks
574 if (Blocks.contains(UseBlock))
575 O.setReg(NewReg);
576 }
577
578 MachineInstrBuilder PHI =
579 BuildMI(*LoopHeader, LoopHeader->getFirstNonPHI(), DebugLoc(),
580 TII->get(TargetOpcode::PHI), NewReg);
581 for (auto *Pred : LoopHeader->predecessors()) {
582 if (Blocks.contains(Pred))
583 PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred);
584 else
585 PHI.addReg(Reg).addMBB(Pred);
586 }
587
588 LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg);
589 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg);
590
591 // Find last use and mark as kill
592 MachineInstr *Kill = nullptr;
593 for (auto *MI : reverse(Instructions)) {
594 if (MI->readsRegister(NewReg, TRI)) {
595 MI->addRegisterKilled(NewReg, TRI);
596 NewVarInfo.Kills.push_back(MI);
597 Kill = MI;
598 break;
599 }
600 }
601 assert(Kill && "Failed to find last usage of register in loop");
602
603 MachineBasicBlock *KillBlock = Kill->getParent();
604 bool PostKillBlock = false;
605 for (auto *Block : Blocks) {
606 auto BBNum = Block->getNumber();
607
608 // collectWaterfallCandidateRegisters only collects registers that are dead
609 // after the loop. So we know that the old reg is no longer live throughout
610 // the waterfall loop.
611 OldVarInfo.AliveBlocks.reset(BBNum);
612
613 // The new register is live up to (and including) the block that kills it.
614 PostKillBlock |= (Block == KillBlock);
615 if (PostKillBlock) {
616 NewVarInfo.AliveBlocks.reset(BBNum);
617 } else if (Block != LoopHeader) {
618 NewVarInfo.AliveBlocks.set(BBNum);
619 }
620 }
621}
622
623char SIOptimizeVGPRLiveRangeLegacy::ID = 0;
624
625INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRangeLegacy, DEBUG_TYPE,
626 "SI Optimize VGPR LiveRange", false, false)
630INITIALIZE_PASS_END(SIOptimizeVGPRLiveRangeLegacy, DEBUG_TYPE,
631 "SI Optimize VGPR LiveRange", false, false)
632
633char &llvm::SIOptimizeVGPRLiveRangeLegacyID = SIOptimizeVGPRLiveRangeLegacy::ID;
634
636 return new SIOptimizeVGPRLiveRangeLegacy();
637}
638
639bool SIOptimizeVGPRLiveRangeLegacy::runOnMachineFunction(MachineFunction &MF) {
640 if (skipFunction(MF.getFunction()))
641 return false;
642
643 LiveVariables *LV = &getAnalysis<LiveVariablesWrapperPass>().getLV();
645 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
646 MachineLoopInfo *Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
647 return SIOptimizeVGPRLiveRange(LV, MDT, Loops).run(MF);
648}
649
650PreservedAnalyses
653 MFPropsModifier _(*this, MF);
657
658 bool Changed = SIOptimizeVGPRLiveRange(LV, MDT, Loops).run(MF);
659 if (!Changed)
660 return PreservedAnalyses::all();
661
663 PA.preserve<LiveVariablesAnalysis>();
664 PA.preserve<DominatorTreeAnalysis>();
665 PA.preserve<MachineLoopAnalysis>();
666 PA.preserveSet<CFGAnalyses>();
667 return PA;
668}
669
670bool SIOptimizeVGPRLiveRange::run(MachineFunction &MF) {
671 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
672 TII = ST.getInstrInfo();
673 TRI = &TII->getRegisterInfo();
674 MRI = &MF.getRegInfo();
675
676 bool MadeChange = false;
677
678 // TODO: we need to think about the order of visiting the blocks to get
679 // optimal result for nesting if-else cases.
680 for (MachineBasicBlock &MBB : MF) {
681 for (auto &MI : MBB.terminators()) {
682 // Detect the if-else blocks
683 if (MI.getOpcode() == AMDGPU::SI_IF) {
684 MachineBasicBlock *IfTarget = MI.getOperand(2).getMBB();
685 auto *Endif = getElseTarget(IfTarget);
686 if (!Endif)
687 continue;
688
689 // Skip unexpected control flow.
690 if (!MDT->dominates(&MBB, IfTarget) || !MDT->dominates(IfTarget, Endif))
691 continue;
692
694 SmallVector<Register> CandidateRegs;
695
696 LLVM_DEBUG(dbgs() << "Checking IF-ELSE-ENDIF: "
697 << printMBBReference(MBB) << ' '
698 << printMBBReference(*IfTarget) << ' '
699 << printMBBReference(*Endif) << '\n');
700
701 // Collect all the blocks in the ELSE region
702 collectElseRegionBlocks(IfTarget, Endif, ElseBlocks);
703
704 // Collect the registers can be optimized
705 collectCandidateRegisters(&MBB, IfTarget, Endif, ElseBlocks,
706 CandidateRegs);
707 MadeChange |= !CandidateRegs.empty();
708 // Now we are safe to optimize.
709 for (auto Reg : CandidateRegs)
710 optimizeLiveRange(Reg, &MBB, IfTarget, Endif, ElseBlocks);
711 } else if (MI.getOpcode() == AMDGPU::SI_WATERFALL_LOOP) {
712 auto *LoopHeader = MI.getOperand(0).getMBB();
713 auto *LoopEnd = &MBB;
714
715 LLVM_DEBUG(dbgs() << "Checking Waterfall loop: "
716 << printMBBReference(*LoopHeader) << '\n');
717
718 SmallSetVector<Register, 16> CandidateRegs;
721
722 collectWaterfallCandidateRegisters(LoopHeader, LoopEnd, CandidateRegs,
723 Blocks, Instructions);
724 MadeChange |= !CandidateRegs.empty();
725 // Now we are safe to optimize.
726 for (auto Reg : CandidateRegs)
727 optimizeWaterfallLiveRange(Reg, LoopHeader, Blocks, Instructions);
728 }
729 }
730 }
731
732 return MadeChange;
733}
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
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
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
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()
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
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:252
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:151
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:339
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
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ 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?