[llvm] AMDGPU: Add NextUseAnalysis Pass (PR #178873)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 13 10:50:39 PDT 2026
================
@@ -0,0 +1,1734 @@
+//===---------------------- 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/CodeGen/MachineDominators.h"
+#include "llvm/IR/ModuleSlotTracker.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ToolOutputFile.h"
+
+#include <cmath>
+#include <limits>
+#include <queue>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "amdgpu-next-use-analysis"
+
+namespace {
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Options
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+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")));
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// String helpers
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+template <typename T> inline std::string printToString(T &X) {
+ std::string S;
+ raw_string_ostream OS(S);
+ X.print(OS);
+ return StringRef(OS.str()).trim().str();
+}
+
+template <typename T> inline std::string printToString(T *X) {
+ return X ? printToString(*X) : "null";
+}
+
+inline std::string printToString(const MachineInstr &MI,
+ ModuleSlotTracker &MST) {
+ std::string S;
+ raw_string_ostream OS(S);
+ MI.print(OS, MST,
+ /* IsStandalone */ false,
+ /* SkipOpers */ false,
+ /* SkipDebugLoc */ false,
+ /* AddNewLine */ false,
+ /* TargetInstrInfo */ nullptr);
+ return StringRef(OS.str()).trim().str();
+}
+
+std::string printRegToString(Register Reg, unsigned SubRegIdx,
+ const MachineRegisterInfo *MRI,
+ const SIRegisterInfo *TRI) {
+ std::string S;
+ raw_string_ostream OS(S);
+ OS << printReg(Reg, TRI, SubRegIdx, MRI);
+ return OS.str();
+}
+
+std::string printRegToString(Register Reg, LaneBitmask LaneMask,
+ const MachineRegisterInfo *MRI,
+ const SIRegisterInfo *TRI) {
+ unsigned SubRegIdx = 0;
+ if (!Reg.isVirtual() || LaneMask != MRI->getMaxLaneMaskForVReg(Reg))
+ SubRegIdx = TRI->getSubRegIndexForLaneMask(LaneMask);
+ return printRegToString(Reg, SubRegIdx, MRI, TRI);
+}
+
+std::string nameForMBB(const MachineBasicBlock &BB, ModuleSlotTracker &MST) {
+ std::string S;
+ raw_string_ostream OS(S);
+ BB.printName(OS, MachineBasicBlock::PrintNameIr, &MST);
+ return OS.str();
+}
+
+struct InstructionInfo {
+ std::string MIStr; // Backing storage for StringRefs
+ StringRef DefName;
+ StringRef DefType;
+ StringRef Instr;
+};
+
+InstructionInfo parseInstructionString(const MachineInstr &MI,
+ ModuleSlotTracker &MST) {
+ InstructionInfo Info;
+ Info.MIStr = printToString(MI, MST);
+ StringRef MIRef(Info.MIStr);
+ StringRef Def;
+ std::tie(Def, Info.Instr) = MIRef.split('=');
+ if (Info.Instr.empty()) {
+ Def = "%void:void";
+ Info.Instr = MIRef;
+ }
+ Info.Instr = Info.Instr.trim();
+ std::tie(Info.DefName, Info.DefType) = Def.trim().split(":");
+ return Info;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/// MBBDistPair - Represents a distance to a machine basic block.
+/// Used for returning both the distance and the target block together.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct MBBDistPair {
+ double Distance;
+ const MachineBasicBlock *MBB;
+ constexpr MBBDistPair()
+ : Distance(std::numeric_limits<double>::max()), MBB(nullptr) {}
+ MBBDistPair(double D, const MachineBasicBlock *B) : Distance(D), MBB(B) {}
+
+ MBBDistPair operator+(double D) { return {Distance + D, MBB}; }
+ MBBDistPair &operator+=(double D) {
+ Distance += D;
+ return *this;
+ }
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/// LiveRegUse - Represents a live register use with its distance.
+/// Used for tracking and sorting register uses by distance.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct LiveRegUse {
+ const MachineOperand *Use = nullptr;
+ double Dist = 0.0;
+ LiveRegUse() = default;
+ LiveRegUse(const MachineOperand *Use, double Dist) : Use(Use), Dist(Dist) {}
+
+ std::string toString() const {
+ if (!valid())
+ return "<invalid>";
+ return std::to_string(Dist) + "@" + printToString(Use) + "*" +
+ printToString(Use->getParent());
+ }
+ bool valid() const { return Use; }
+
+ Register getReg() const { return Use->getReg(); }
+ LaneBitmask getLaneMask(const SIRegisterInfo *TRI) const {
+ return TRI->getSubRegIndexLaneMask(Use->getSubReg());
+ }
+
+ bool operator<(const LiveRegUse &Other) const {
+ if (!Use)
+ return true; // Other is better
+
+ if (Dist < Other.Dist)
+ return true; // Other is better
+
+ if (Dist != Other.Dist)
+ return false; // this is better
+
+ if (Use == Other.Use)
+ return false; // this is better
+
+ // 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.
----------------
macurtis-amd wrote:
See comment [here](https://github.com/llvm/llvm-project/pull/178873#discussion_r3074795540).
https://github.com/llvm/llvm-project/pull/178873
More information about the llvm-commits
mailing list