[llvm] AMDGPU: Add NextUseAnalysis Pass (PR #178873)
Konstantina Mitropoulou via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 25 22:07:00 PDT 2026
================
@@ -0,0 +1,2349 @@
+//===---------------------- AMDGPUNextUseAnalysis.cpp ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPUNextUseAnalysis.h"
+#include "AMDGPU.h"
+#include "GCNRegPressure.h"
+#include "GCNSubtarget.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/IR/ModuleSlotTracker.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <queue>
+#include <string>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "amdgpu-next-use-analysis"
+
+//==============================================================================
+// Options etc
+//==============================================================================
+namespace {
+
+cl::opt<bool> DumpNextUseDistance("amdgpu-next-use-analysis-dump-distance",
+ cl::init(false), cl::Hidden);
+
+cl::opt<std::string>
+ DumpNextUseDistanceAsJson("amdgpu-next-use-analysis-dump-distance-as-json",
+ cl::Hidden);
+cl::opt<bool>
+ DumpNextUseDistanceVerbose("amdgpu-next-use-analysis-dump-distance-verbose",
+ cl::init(false), cl::Hidden);
+
+cl::opt<AMDGPUNextUseAnalysis::CompatibilityMode> CompatModeOpt(
+ "amdgpu-next-use-analysis-compatibility-mode", cl::Hidden,
+ cl::init(AMDGPUNextUseAnalysis::CompatibilityMode::Graphics),
+ cl::values(clEnumValN(AMDGPUNextUseAnalysis::CompatibilityMode::Graphics,
+ "graphics", "TBD"),
+ clEnumValN(AMDGPUNextUseAnalysis::CompatibilityMode::Compute,
+ "compute", "TBD")));
+} // namespace
+
+//==============================================================================
+// LiveRegUse - Represents a live register use with its distance. Used for
+// tracking and sorting register uses by distance.
+//==============================================================================
+namespace {
+using UseDistancePair = AMDGPUNextUseAnalysis::UseDistancePair;
+struct LiveRegUse : public UseDistancePair {
+ // 'nullptr' indicates an unset/invalid state.
+ LiveRegUse() : UseDistancePair(nullptr, 0) {}
+ LiveRegUse(const MachineOperand *Use, NextUseDistance Dist)
+ : UseDistancePair(Use, Dist) {}
+ LiveRegUse(const UseDistancePair &P) : UseDistancePair(P) {}
+
+ bool isUnset() const { return Use == nullptr; }
+
+ Register getReg() const { return Use->getReg(); }
+ unsigned getSubReg() const { return Use->getSubReg(); }
+ LaneBitmask getLaneMask(const SIRegisterInfo *TRI) const {
+ return TRI->getSubRegIndexLaneMask(Use->getSubReg());
+ }
+
+ bool isCloserThan(const LiveRegUse &X) const {
+ if (Dist < X.Dist)
+ return true;
+
+ if (Dist > X.Dist)
+ return false;
+
+ if (Use == X.Use)
+ return false;
+
+ // Ugh. In computeMode PHIs and the first non-PHI instruction have id
+ // 0. In this case, consider PHIs as less than the first non-PHI
+ // instruction.
+ const MachineInstr *ThisMI = Use->getParent();
+ const MachineInstr *XMI = X.Use->getParent();
+ const MachineBasicBlock *ThisMBB = ThisMI->getParent();
+ if (ThisMBB == XMI->getParent()) {
+ bool XIsPhiOp = ThisMI->isPHI();
+ bool YIsPhiOp = XMI->isPHI();
+ if (XIsPhiOp && !YIsPhiOp && XMI == &(*ThisMBB->getFirstNonPHI()))
+ return true;
+ }
+
+ // Ensure deterministic results
+ return X.getReg() < getReg();
+ }
+};
+
+inline bool updateClosest(LiveRegUse &Closest, const LiveRegUse &X) {
+ if (!Closest.Use || X.isCloserThan(Closest)) {
+ Closest = X;
+ return true;
+ }
+ return false;
+}
----------------
kmitropoulou wrote:
Can you please add a dump() function here and in other classes to help with debugging?
https://github.com/llvm/llvm-project/pull/178873
More information about the llvm-commits
mailing list