1+ // ===-- AMDGPUNextUseAnalysis.cpp - Next Use Analysis ---------------------===//
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 file implements the Next Use Analysis for AMDGPU targets.
11+ //
12+ // ===----------------------------------------------------------------------===//
13+
114#include " AMDGPUNextUseAnalysis.h"
215#include " AMDGPU.h"
316
417#include " llvm/ADT/DenseMap.h"
518#include " llvm/ADT/PostOrderIterator.h"
619#include " llvm/ADT/iterator_range.h"
20+ #include " llvm/CodeGen/MachineBasicBlock.h"
721#include " llvm/CodeGen/MachineDominators.h"
822#include " llvm/CodeGen/MachineFunction.h"
923#include " llvm/CodeGen/MachineFunctionAnalysis.h"
@@ -60,10 +74,10 @@ unsigned NextUseResult::materializeForRank(int64_t Stored,
6074}
6175
6276void NextUseResult::init (const MachineFunction &MF) {
63- for (const auto *L : LI->getLoopsInPreorder ()) {
77+ for (const MachineLoop *L : LI->getLoopsInPreorder ()) {
6478 SmallVector<std::pair<MachineBasicBlock *, MachineBasicBlock *>> Exiting;
6579 L->getExitEdges (Exiting);
66- for (const auto &P : Exiting) {
80+ for (const std::pair<MachineBasicBlock *, MachineBasicBlock *> &P : Exiting) {
6781 LoopExits[P.first ->getNumber ()] = P.second ->getNumber ();
6882 }
6983 }
@@ -75,25 +89,28 @@ void NextUseResult::analyze(const MachineFunction &MF) {
7589 // function as the analysis users are only interested in the use distances
7690 // relatively to the given MI or the given block end.
7791 DenseMap<unsigned , VRegDistances> UpwardNextUses;
92+ iterator_range<po_iterator<const llvm::MachineFunction *>> POT =
93+ post_order (&MF);
7894 if (EnableTimers)
7995 AnalyzeTimer.startTimer ();
8096 bool Changed = true ;
8197 while (Changed) {
8298 Changed = false ;
83- for (const auto *MBB : post_order (&MF) ) {
99+ for (const MachineBasicBlock *MBB : POT ) {
84100 unsigned Offset = 0 ;
85101 unsigned MBBNum = MBB->getNumber ();
86102 VRegDistances Curr, Prev;
87- if (UpwardNextUses.contains (MBBNum)) {
88- Prev = UpwardNextUses[MBBNum];
103+ DenseMap<unsigned , VRegDistances>::iterator PrevIt = UpwardNextUses.find (MBBNum);
104+ if (PrevIt != UpwardNextUses.end ()) {
105+ Prev = PrevIt->second ;
89106 }
90107
91108 LLVM_DEBUG ({
92109 dbgs () << " \n Merging successors for "
93110 << " MBB_" << MBB->getNumber () << " ." << MBB->getName () << " \n " ;
94111 });
95112
96- for (auto *Succ : successors (MBB)) {
113+ for (MachineBasicBlock *Succ : successors (MBB)) {
97114 unsigned SuccNum = Succ->getNumber ();
98115
99116 if (!UpwardNextUses.contains (SuccNum))
@@ -108,8 +125,9 @@ void NextUseResult::analyze(const MachineFunction &MF) {
108125
109126 // Check if the edge from MBB to Succ goes out of the Loop
110127 int64_t EdgeWeight = 0 ;
111- if (LoopExits.contains (MBB->getNumber ())) {
112- if (SuccNum == LoopExits[MBB->getNumber ()])
128+ DenseMap<unsigned , unsigned >::iterator LoopExitIt = LoopExits.find (MBB->getNumber ());
129+ if (LoopExitIt != LoopExits.end ()) {
130+ if (SuccNum == LoopExitIt->second )
113131 EdgeWeight = LoopTag;
114132 }
115133
@@ -119,10 +137,9 @@ void NextUseResult::analyze(const MachineFunction &MF) {
119137 // 1. Outside-loop uses (>= LoopTag): subtract LoopTag
120138 // 2. Inside-loop uses (< LoopTag): reset to preheader position
121139 // This models: if spilled before loop, reload at preheader
122- for (auto &P : SuccDist) {
123- auto &Dists = P.second ;
140+ for (auto &[VReg, Dists] : SuccDist) {
124141 VRegDistances::SortedRecords NewDists;
125- for (auto R : Dists) {
142+ for (VRegDistances::Record R : Dists) {
126143 if (R.second >= LoopTag) {
127144 // Outside-loop use: subtract LoopTag
128145 R.second -= LoopTag;
@@ -147,7 +164,7 @@ void NextUseResult::analyze(const MachineFunction &MF) {
147164
148165 // Filter out successor's PHI operands with SourceBlock != MBB
149166 // PHI operands are only live on their specific incoming edge
150- for (auto &PHI : Succ->phis ()) {
167+ for (MachineInstr &PHI : Succ->phis ()) {
151168 // Check each PHI operand pair (value, source block)
152169 for (unsigned OpIdx = 1 ; OpIdx < PHI.getNumOperands (); OpIdx += 2 ) {
153170 const MachineOperand &UseOp = PHI.getOperand (OpIdx);
@@ -171,9 +188,9 @@ void NextUseResult::analyze(const MachineFunction &MF) {
171188
172189 NextUseMap[MBBNum].Bottom = Curr;
173190
174- for (auto &MI : make_range ( MBB-> rbegin (), MBB-> rend () )) {
191+ for (const MachineInstr &MI : reverse (* MBB)) {
175192
176- for (auto &MO : MI.operands ()) {
193+ for (const MachineOperand &MO : MI.operands ()) {
177194
178195 // Only process virtual register operands
179196 // Undef operands don't represent real uses
@@ -200,11 +217,9 @@ void NextUseResult::analyze(const MachineFunction &MF) {
200217 // materialization
201218
202219 LLVM_DEBUG ({
203- dbgs () << " \n Final distances for MBB_" << MBB->getNumber () << " ."
204- << MBB->getName () << " \n " ;
220+ dbgs () << " \n Final distances for " << printMBBReference (*MBB) << " \n " ;
205221 printVregDistances (Curr, Offset);
206- dbgs () << " \n Previous distances for MBB_" << MBB->getNumber () << " ."
207- << MBB->getName () << " \n " ;
222+ dbgs () << " \n Previous distances for " << printMBBReference (*MBB) << " \n " ;
208223 printVregDistances (Prev, Offset);
209224 dbgs () << " \n Used in block:\n " ;
210225 dumpUsedInBlock ();
@@ -238,7 +253,7 @@ void NextUseResult::getFromSortedRecords(
238253 // Records are sorted by stored value in increasing order. Since all entries
239254 // in this snapshot share the same SnapshotOffset, ordering by stored value
240255 // is equivalent to ordering by materialized distance.
241- for (const auto &P : Dists) {
256+ for (const VRegDistances::Record &P : Dists) {
242257 const LaneBitmask UseMask = P.first ;
243258 LLVM_DEBUG (dbgs () << " UseMask : [" << PrintLaneMask (UseMask) << " ]\n " );
244259
@@ -259,30 +274,36 @@ void NextUseResult::getFromSortedRecords(
259274 }
260275}
261276
277+ // Helper to collect subreg uses from sorted records
278+ static void collectSubregUses (const NextUseResult::VRegDistances::SortedRecords &Dists,
279+ const VRegMaskPair &VMP,
280+ SmallVectorImpl<VRegMaskPair> &Result) {
281+ LLVM_DEBUG ({ dbgs () << " Mask : [" << PrintLaneMask (VMP.getLaneMask ()) << " ]\n " ; });
282+ for (const NextUseResult::VRegDistances::Record &P : reverse (Dists)) {
283+ LaneBitmask UseMask = P.first ;
284+ LLVM_DEBUG ({ dbgs () << " Used mask : [" << PrintLaneMask (UseMask) << " ]\n " ; });
285+ if ((UseMask & VMP.getLaneMask ()) == UseMask) {
286+ Result.push_back ({VMP.getVReg (), UseMask});
287+ }
288+ }
289+ }
290+
262291SmallVector<VRegMaskPair>
263292NextUseResult::getSortedSubregUses (const MachineBasicBlock::iterator I,
264293 const VRegMaskPair VMP) {
265294 SmallVector<VRegMaskPair> Result;
266295 const MachineBasicBlock *MBB = I->getParent ();
267296 unsigned MBBNum = MBB->getNumber ();
268- if (NextUseMap.contains (MBBNum) &&
269- NextUseMap[MBBNum].InstrDist .contains (&*I)) {
270- if (NextUseMap[MBBNum].InstrDist [&*I].contains (VMP.getVReg ())) {
271- VRegDistances::SortedRecords Dists =
272- NextUseMap[MBBNum].InstrDist [&*I][VMP.getVReg ()];
273- LLVM_DEBUG ({
274- dbgs () << " Mask : [" << PrintLaneMask (VMP.getLaneMask ()) << " ]\n " ;
275- });
276- for (auto P : reverse (Dists)) {
277- LaneBitmask UseMask = P.first ;
278- LLVM_DEBUG (
279- { dbgs () << " Used mask : [" << PrintLaneMask (UseMask) << " ]\n " ; });
280- if ((UseMask & VMP.getLaneMask ()) == UseMask) {
281- Result.push_back ({VMP.getVReg (), UseMask});
282- }
283- }
284- }
285- }
297+ DenseMap<unsigned , NextUseInfo>::iterator MBBIt = NextUseMap.find (MBBNum);
298+ if (MBBIt == NextUseMap.end ())
299+ return Result;
300+ DenseMap<const MachineInstr *, VRegDistances>::iterator InstrIt = MBBIt->second .InstrDist .find (&*I);
301+ if (InstrIt == MBBIt->second .InstrDist .end ())
302+ return Result;
303+ VRegDistances::iterator VRegIt = InstrIt->second .find (VMP.getVReg ());
304+ if (VRegIt == InstrIt->second .end ())
305+ return Result;
306+ collectSubregUses (VRegIt->second , VMP, Result);
286307 return Result;
287308}
288309
@@ -291,27 +312,20 @@ NextUseResult::getSortedSubregUses(const MachineBasicBlock &MBB,
291312 const VRegMaskPair VMP) {
292313 SmallVector<VRegMaskPair> Result;
293314 unsigned MBBNum = MBB.getNumber ();
294- if (NextUseMap.contains (MBBNum) &&
295- NextUseMap[MBBNum].Bottom .contains (VMP.getVReg ())) {
296- VRegDistances::SortedRecords Dists =
297- NextUseMap[MBBNum].Bottom [VMP.getVReg ()];
298- LLVM_DEBUG (
299- { dbgs () << " Mask : [" << PrintLaneMask (VMP.getLaneMask ()) << " ]\n " ; });
300- for (auto P : reverse (Dists)) {
301- LaneBitmask UseMask = P.first ;
302- LLVM_DEBUG (dbgs () << " Used mask : [" << PrintLaneMask (UseMask) << " ]\n " );
303- if ((UseMask & VMP.getLaneMask ()) == UseMask) {
304- Result.push_back ({VMP.getVReg (), UseMask});
305- }
306- }
307- }
315+ DenseMap<unsigned , NextUseInfo>::iterator MBBIt = NextUseMap.find (MBBNum);
316+ if (MBBIt == NextUseMap.end ())
317+ return Result;
318+ VRegDistances::iterator VRegIt = MBBIt->second .Bottom .find (VMP.getVReg ());
319+ if (VRegIt == MBBIt->second .Bottom .end ())
320+ return Result;
321+ collectSubregUses (VRegIt->second , VMP, Result);
308322 return Result;
309323}
310324
311325void NextUseResult::dumpUsedInBlock () {
312- for (auto P : UsedInBlock) {
313- dbgs () << " MBB_" << P. first << " :\n " ;
314- for (auto VMP : P. second ) {
326+ for (auto &[MBBNum, VMPs] : UsedInBlock) {
327+ dbgs () << " MBB_" << MBBNum << " :\n " ;
328+ for (const VRegMaskPair & VMP : VMPs ) {
315329 dbgs () << " [ " << printReg (VMP.getVReg ()) << " : <"
316330 << PrintLaneMask (VMP.getLaneMask ()) << " > ]\n " ;
317331 }
@@ -326,14 +340,15 @@ unsigned NextUseResult::getNextUseDistance(const MachineBasicBlock::iterator I,
326340 unsigned Dist = DeadDistance;
327341 const MachineBasicBlock *MBB = I->getParent ();
328342 unsigned MBBNum = MBB->getNumber ();
329- if (NextUseMap.contains (MBBNum) &&
330- NextUseMap[MBBNum].InstrDist .contains (&*I)) {
331- VRegDistances Dists = NextUseMap[MBBNum].InstrDist [&*I];
332- if (NextUseMap[MBBNum].InstrDist [&*I].contains (VMP.getVReg ())) {
333- // printSortedRecords(Dists[VMP.VReg], VMP.VReg);
334- unsigned SnapOff = NextUseMap[MBBNum].InstrOffset [&*I];
335- getFromSortedRecords (Dists[VMP.getVReg ()], VMP.getLaneMask (), SnapOff,
336- Dist);
343+ DenseMap<unsigned , NextUseInfo>::iterator MBBIt = NextUseMap.find (MBBNum);
344+ if (MBBIt != NextUseMap.end ()) {
345+ DenseMap<const MachineInstr *, VRegDistances>::iterator InstrIt = MBBIt->second .InstrDist .find (&*I);
346+ if (InstrIt != MBBIt->second .InstrDist .end ()) {
347+ VRegDistances::iterator VRegIt = InstrIt->second .find (VMP.getVReg ());
348+ if (VRegIt != InstrIt->second .end ()) {
349+ unsigned SnapOff = MBBIt->second .InstrOffset .lookup (&*I);
350+ getFromSortedRecords (VRegIt->second , VMP.getLaneMask (), SnapOff, Dist);
351+ }
337352 }
338353 }
339354
@@ -349,10 +364,11 @@ unsigned NextUseResult::getNextUseDistance(const MachineBasicBlock &MBB,
349364
350365 unsigned Dist = DeadDistance;
351366 unsigned MBBNum = MBB.getNumber ();
352- if (NextUseMap.contains (MBBNum)) {
353- if (NextUseMap[MBBNum].Bottom .contains (VMP.getVReg ())) {
354- getFromSortedRecords (NextUseMap[MBBNum].Bottom [VMP.getVReg ()],
355- VMP.getLaneMask (), 0 , Dist);
367+ DenseMap<unsigned , NextUseInfo>::iterator MBBIt = NextUseMap.find (MBBNum);
368+ if (MBBIt != NextUseMap.end ()) {
369+ VRegDistances::iterator VRegIt = MBBIt->second .Bottom .find (VMP.getVReg ());
370+ if (VRegIt != MBBIt->second .Bottom .end ()) {
371+ getFromSortedRecords (VRegIt->second , VMP.getLaneMask (), 0 , Dist);
356372 }
357373 }
358374
@@ -408,7 +424,7 @@ void NextUseResult::dumpAllNextUseDistances(const MachineFunction &MF) {
408424 LLVM_DEBUG (dbgs () << " === NextUseAnalysis Results for " << MF.getName ()
409425 << " ===\n " );
410426
411- for (const auto &MBB : MF) {
427+ for (const MachineBasicBlock &MBB : MF) {
412428 const unsigned MBBNum = MBB.getNumber ();
413429 LLVM_DEBUG (dbgs () << " \n --- MBB_" << MBBNum << " ---\n " );
414430
@@ -420,7 +436,7 @@ void NextUseResult::dumpAllNextUseDistances(const MachineFunction &MF) {
420436 const NextUseInfo &Info = NextUseMap.at (MBBNum);
421437
422438 // Per-instruction dump (materialized with per-MI snapshot offset).
423- for (auto II = MBB.begin (), IE = MBB.end (); II != IE; ++II) {
439+ for (MachineBasicBlock::const_iterator II = MBB.begin (), IE = MBB.end (); II != IE; ++II) {
424440 const MachineInstr &MI = *II;
425441
426442 LLVM_DEBUG (dbgs () << " Instr: " );
@@ -429,8 +445,9 @@ void NextUseResult::dumpAllNextUseDistances(const MachineFunction &MF) {
429445 LLVM_DEBUG (dbgs () << " \n " );
430446
431447 LLVM_DEBUG (dbgs () << " Next-use distances:\n " );
432- if (Info.InstrDist .contains (&MI)) {
433- const VRegDistances &Dists = Info.InstrDist .at (&MI);
448+ DenseMap<const MachineInstr *, VRegDistances>::const_iterator InstrIt = Info.InstrDist .find (&MI);
449+ if (InstrIt != Info.InstrDist .end ()) {
450+ const VRegDistances &Dists = InstrIt->second ;
434451 const unsigned SnapOff = Info.InstrOffset .lookup (&MI); // 0 if absent
435452 const bool Any =
436453 printVregDistances (Dists, SnapOff, 0 , dbgs (), " " );
0 commit comments