Skip to content

Commit 317b811

Browse files
committed
[AMDGPU][Next Use Analysis] All 'auto' changed for exact types. Double maps lookups refactored. Other review comments addressed.
1 parent 54fc75e commit 317b811

File tree

2 files changed

+126
-109
lines changed

2 files changed

+126
-109
lines changed

llvm/lib/Target/AMDGPU/AMDGPUNextUseAnalysis.cpp

Lines changed: 87 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
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

6276
void 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() << "\nMerging 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() << "\nFinal distances for MBB_" << MBB->getNumber() << "."
204-
<< MBB->getName() << "\n";
220+
dbgs() << "\nFinal distances for " << printMBBReference(*MBB) << "\n";
205221
printVregDistances(Curr, Offset);
206-
dbgs() << "\nPrevious distances for MBB_" << MBB->getNumber() << "."
207-
<< MBB->getName() << "\n";
222+
dbgs() << "\nPrevious distances for " << printMBBReference(*MBB) << "\n";
208223
printVregDistances(Prev, Offset);
209224
dbgs() << "\nUsed 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+
262291
SmallVector<VRegMaskPair>
263292
NextUseResult::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

311325
void 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

Comments
 (0)