[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