[llvm] [AMDGPU][NewInsertWaitcnt] Add Event Tracker (PR #226970)

Pierre van Houtryve via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 06:50:23 PDT 2026


================
@@ -0,0 +1,618 @@
+//===- AMDGPUEventTrackingTest.cpp ------------------------------*- C++ -*-===//
+//
+// 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 "AMDGPUEventTracking.h"
+#include "AMDGPUUnitTests.h"
+#include "AMDGPUWaitcntUtils.h"
+#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::AMDGPU;
+using namespace llvm::AMDGPU::eventtracking;
+
+namespace {
+
+static constexpr unsigned CounterLimit = 12;
+
+// These are not accurate, they are simply for testing purposes.
+// We do not need to test every single counter accurately, that is the job
+// of the IR/MIR tests in tests/CodeGen/AMDGPU. We just need enough here
+// to validate that the EventTracker works.
+std::array<CounterInfo, 4> GFX12CounterInfos = {{
+    {LOAD_CNT, HWEvents::VMEM_READ_ACCESS, CounterLimit},
+    {DS_CNT, HWEvents::LDS_ACCESS, CounterLimit},
+    {EXP_CNT, HWEvents::EXP_GPR_LOCK, CounterLimit},
+    {STORE_CNT, HWEvents::VMEM_WRITE_ACCESS | HWEvents::SCRATCH_WRITE_ACCESS,
+     CounterLimit},
+}};
+
+class AMDGPUGFX12EventTrackingTest : public AMDGPUCodeGenTestBase {
+public:
+  void SetUp() override { setUpImpl("amdgpu12.00-amd-amdhsa", "gfx1200", ""); }
+};
+
+namespace {
+static EventTracker &
+visitAll(EventTrackingContext &Ctx, MachineBasicBlock &MBB,
+         function_ref<void(EventTracker &ET)> AfterVisit = nullptr) {
+  const GCNSubtarget &ST = MBB.getParent()->getSubtarget<GCNSubtarget>();
+
+  EventTracker &ET = Ctx[&MBB];
+  ET.enterBlock();
+  for (MachineInstr &MI : MBB) {
+    HWEvents Events =
+        getEventsFor(MI, ST, /*IsExpertMode=*/false, /*TgSplit=*/false);
+    for (HWEvents SingleEv : Events) {
+      ET.record(MI, SingleHWEvent::encode(SingleEv));
+    }
+  }
+  if (AfterVisit)
+    AfterVisit(ET);
+  ET.leaveBlock();
+  return ET;
+}
+
+/// Provides some helpers to declaratively check the state of the EventTracker
+/// for one counter. This provides helpers to check the general counter state
+/// (value, etc) but also allows iterating over the timeline from the oldest to
+/// the earliest element.
+///
+/// This makes the actual test cases clearer.
+struct TrackerRecordsChecker {
+  TrackerRecordsChecker(EventTracker &ET, InstCounterType T)
+      : ET(ET), T(T), Records(ET.getLiveRecords(T)) {}
+
+  bool hasCount() { return ET.count(T).has_value(); }
+
+  unsigned getCount() { return *ET.count(T); }
+
+  bool empty() { return Records.empty(); }
+
+  // Has no records and score is zero (if there is one)
+  bool unused() { return empty() && (!hasCount() || !getCount()); }
+
+  const EventTrackerRecord &cur() { return Records[CurElt]; }
+
+  /// Move to the next record.
+  /// \returns true on success, false if the end has been reached.
+  bool next() {
+    ++CurElt;
+    if (CurElt >= Records.size())
+      return false;
+    return true;
+  }
+
+  EventTracker &ET;
+  InstCounterType T;
+  ArrayRef<EventTrackerRecord> Records;
+  unsigned CurElt = 0;
+};
+
+} // namespace
+
+/// Check trivial straight line counting.
+TEST_F(AMDGPUGFX12EventTrackingTest, BasicTimeline) {
+  StringRef MIR = R"(
+name:            BasicTimeline
+body:             |
+  bb.0:
+
+    GLOBAL_STORE_DWORD $vgpr0_vgpr1, $vgpr2, 0, 0, implicit $exec
----------------
Pierre-vh wrote:

No need, pass doesn't lean on MMOs at all

https://github.com/llvm/llvm-project/pull/226970


More information about the llvm-commits mailing list