336 Commits

Author SHA1 Message Date
vporpo
368f38b9fc
[AMDGPU][SIInsertWaitcnts][NFC] SGPRInfo: Move score selection logic closer (#186518)
Selecting the score in SGPRInfo used to require an index which you would
get by calling a getSgprScoresIdx(), which is defined in a different
class.

This patch moves the score selection logic into the SGPRinfo. This makes
the interface simpler and more intuitive.

Also given that SGPRInfo contains only two scores, this patch also
replaces the score array with individual score variables.

Should be NFC.
2026-03-20 16:30:52 -07:00
Sameer Sahasrabuddhe
e6789f94b9
[AMDGPU] Introduce ASYNC_CNT on GFX1250 (#185810)
Async operations transfer data between global memory and LDS. Their
progress is tracked by the ASYNC_CNT counter on GFX1250 and later
architectures. This change introduces the representation of that counter
in SIInsertWaitCnts. For now, the programmer must manually insert
s_wait_asyncnt instructions. Later changes will add compiler assistance
for generating the waits by including this counter in the asyncmark
instructions.

Assisted-by: Claude Sonnet 4.5

This is part of a stack:

- #185813
- #185810
2026-03-20 09:52:05 +00:00
Jay Foad
8086888787
[AMDGPU] Make WaitcntBrackets::Limits a reference. NFC. (#186782) 2026-03-16 12:16:38 +00:00
Jay Foad
d3417c8bf3
[AMDGPU] Simplify state clearing in SIInsertWaitcnts. NFC. (#186399)
There is no need to clear state at the start or end of the run method,
because a fresh instance of SIInsertWaitcnts is constructed for each run
on a MachineFunction.
2026-03-16 10:06:59 +00:00
Jay Foad
2323fb31cc
[AMDGPU] Initialize more fields in the SIInsertWaitcnts constructor. NFC. (#186394)
ST, TII, TRI and MRI can all be initialized in the constructor and hence
be references instead of pointers.
2026-03-16 10:05:05 +00:00
Jay Foad
d7a388c39b
[AMDGPU] Pass MF into the SIInsertWaitcnts constructor. NFC. (#186369)
Pass MF into the SIInsertWaitcnts constructor instead of the run method.
This is more natural now that SIInsertWaitcnts is constructed once per
MachineFunction and enables future cleanup by initializing more fields
in the constructor that depend on MF.
2026-03-13 13:22:38 +00:00
Jay Foad
15b188835f
[AMDGPU] Change SIInsertWaitcnts MLI and PDT to references. NFC. (#186367)
These analyses are always available.
2026-03-13 11:46:27 +00:00
vporpo
203c5c58f2
[AMDGPU][SIInsertWaitcnts] Create a WCG instance per MF (#185916)
WaitcntGenerator state depends on MF attributes, so create a new WCG object per MF
until we have a better solution. This patch also adds a test that exercises this.

Even though we stopped creating a new WCG instance in #177689, the behavior
didn't change because SIInsertWaitcnts gets recreated on every MF
(so this patch is practically an NFC).
2026-03-12 16:34:18 -07:00
Sameer Sahasrabuddhe
76cfb0b68e [NFC][AMDGPU] WaitEventSet should only print events that it contains 2026-03-09 11:12:41 +05:30
vporpo
dc8de1083e
[AMDGPU][SIInsertWaitcnts][NFC] Simplify logic in GFX12Plus::applyPreexistingWaitcnts (#184925)
The loop is collecting the first instruction of each waitcnt kind and is
erasing the rest, with the exception of DEPCTR which needs more checks.
The existing code was factoring out the instruction deletion and the
setting of the collected instruction variables. But the special handling
for DEPCTR and the in-loop deletion of `S_WAITCNT_lds_direct` was just
complicating the logic.
2026-03-06 13:59:12 -08:00
Ryan Mitchell
918d0feb76
[AMDGPU] fix asyncmark soft waitcnt bug (#184851)
Asyncmarks record the current wait state and so should not allow waitcnts that occur after them to be merged into waitcnts that occur before.
2026-03-06 11:38:32 -08:00
vporpo
fe76fd292c
[AMDGPU][SIInsertWaitcnts][NFC] Call applyWaitcnt() in a loop (#184426) 2026-03-03 13:13:21 -08:00
hidekisaito
9d1fd9ec1e
[AMDGPU] Extend DS loop wait optimization with flush point tracking (#175658)
Add support for prefetch patterns where some DS loads are used in the
same iteration (creating flush points) while others remain unflushed at
the backedge.

This complements the existing pure prefetch optimization (PR172728) by
handling cases where partial same-iteration consumption occurs.

Assisted-by: Cursor / claude-4.5-opus-high
2026-03-02 09:19:46 -08:00
vporpo
342e44603d
[AMDGPU][SIInsertWaitcnts] Move VCCZ workaround code out of the way (#182619)
This is a cleanup patch that moves the VCCZ specific workaround code
from `SIInsertWaitcnts::insertWaitcntInBlock()` to a separate class and
refactors it a bit to make it easier to read.
The end result is a simpler `insertWaitcntInBlock()`.

Should be NFC.
2026-02-27 17:28:03 -08:00
vporpo
5a756c8a3a
[AMDGPU][SIInsertWaitcnts][NFC] Make Waitcnt members private (#180772)
This patch makes Waitcnt member variables private and replaces their
accesses with calls to set() or get(). This will help us change the
implementation to an a array in the followup patch.
2026-02-23 11:44:19 -08:00
vporpo
bad9e4a849
[AMDGPU][SIInsertWaitcnts][NFC] Move instr events code into separate function (#180864)
This patch moves the code that finds which events correspond to an
instruction into a separate `getEventsFor(MachineInstr)` function.
2026-02-23 11:34:04 -08:00
vporpo
494bc4ca12
[AMDGPU][SIInsertWaitcnts][NFC] Clean up loop (#179572)
After merging https://github.com/llvm/llvm-project/pull/181760 this loop
no longer erases instructions while iterating. So this patch moves the
iteration increment inside the for statement.

Note: Replacing the loop with a range loop like `for (MachineInstr
&Instr : Block)` is not an NFC.
2026-02-20 10:34:50 -08:00
hidekisaito
969a326386
[AMDGPU] BackOffBarrier feature added to gfx1250; Removed incorrect "DS Store drain" check. (#179818)
Missing BackOffBarrier feature added to gfx1250.
Checking for S_BARRIER only does not imply prior DS Stores getting
drained.
2026-02-19 08:41:44 -08:00
Sameer Sahasrabuddhe
c5ac41dba8
[AMDGPU][NFC] Minor source cleanups in SIInsertWaitcnts (#181095) 2026-02-18 10:53:02 +05:30
vporpo
5addddf8f1
[AMDGPU][SIInsertWaitcnts][NFC] Move soft xcnt deletion to separate function (#181760)
This patch simplifies the logic of `insertWaitcntInBlock()` by moving
the code that removes the redundant soft xcnt instructions to a new
function: `removeRedundantSoftXcnts()`.

While doing so, this patch also cleans up the logic a bit by dropping
the AtomiRMWState and the corresponding functions.

This helps in several ways:
- insertWaitcntInBlock() will now do what its name suggests, i.e., only
insert and not remove.
- it makes it clear that removal of softxcnts is orthogonal to insertion
of waitcnts.
- we won't have to worry about both erased and new instruction in
insertWaitcntInBlock()'s loop.

The change should be NFC.
2026-02-17 09:24:08 -08:00
Sameer Sahasrabuddhe
128437fb6a
[AMDGPU] Introduce asyncmark/wait intrinsics (#180467)
Asynchronous operations are memory transfers (usually between the global
memory and LDS) that are completed independently at an unspecified
scope. A thread that requests one or more asynchronous transfers can use
async marks to track their completion. The thread waits for each mark to
be completed, which indicates that requests initiated in program order
before this mark have also completed.

For now, we implement asyncmark/wait operations on pre-GFX12
architectures that support "LDS DMA" operations. Future work will extend
support to GFX12Plus architectures that support "true" async operations.

This is part of a stack split out from #173259
- #180467
- #180466

Co-authored-by: Ryan Mitchell ryan.mitchell@amd.com

Fixes: SWDEV-521121
2026-02-11 07:15:51 +00:00
vporpo
9898082bd3
[AMDGPU][SIInsertWaitcnt][NFC] Access Waitcnt elements using InstCounterType (#178345)
This patch introduces `get(T)` and `set(T, Val)` functions for Waitcnt
and removes getCounterRef() and getWait(). For this to work we also need
to move InstrCounterType to AMDGPUBaseInfo.h.

Please note that the member variables are still public to keep this
patch small.
They will be replaced in the follow-up patch.
2026-02-09 17:54:08 -08:00
vporpo
88dff28c9f
[AMDGPU][SIInsertWaitcnts][NFC] Make a few WaitcntBracket member functions private (#180018)
The user of the WaitcntBrackets class shouldn't need to know about how
the scoreboard has been implemented internally. So I think it is best to
provide a higher level API that hides things like scoreUB, scoreLB and
score ranges.

This patch makes getScoreUB(), getScoreLB() and getScoreRange() private
and introduces new functions that don't expose the internal
implementation:
- getOutstanding(T)
- hasPendingVMEM(VMEMID, T)
- empty(T)

I also noticed that getSGPRScore() and getVMemScore() are not used
externally so these are now private.
2026-02-07 13:55:01 -08:00
vporpo
7022e5a514
[AMDGPU][SIINsertWaitcnts][NFC] Make TTI and ST references (#180017)
This patch converts WaitcntGenerator::TTI and ST pointers to references.
This helps remove some null checking assertions.
2026-02-05 13:18:06 -08:00
vporpo
5326166866
[AMDGPU][SIInsertWaitcnt][NFC] Don't expose internal data structure to user (#179736)
With this patch we are no longer exposing the internal data structure
that holds the WaitEvents to the user through the `getWaitEventMask()`
API. Instead we only allow the user to query a specific type and get the
corresponding `WaitEventSet` with `getWaitEvents(T)`.
Note: This patch also renames `getWaitEventMask()` to `getWaitEvents()`
because we are no longer returning a mask but instead a `WaitEventSet`
object.
2026-02-05 11:07:38 -08:00
Vigneshwar Jayakumar
2dcd75eb44
[AMDGPU] Fix missing waitcnt after buffer_wbl2 (#178316)
On GFX9, BUFFER_WBL2 is used to write back dirty cache lines and
requires an s_waitcnt vmcnt(0) afterwards to ensure completion.

This patch fixes by incrementing vmcnt for buffer_wbl2 instruction

---------

Co-authored-by: Jay Foad <jay.foad@gmail.com>
2026-02-05 10:13:51 -06:00
vporpo
d9da5d7626
[AMDGPU][SIInsertWaitcnt][NFC] Move eventCounter() function (#178949)
The eventCounter() function searches through the array of events. This
array is owned by the WaitcntGenerator class.

This patch moves the function into the WaitcntGenerator class which
helps hide the event array from the user.
It also renames it to getCounterFromEvent().

This should be NFC.
2026-02-04 11:11:18 -08:00
vporpo
3c67dcb2f2
[AMDGPU][SIInsertWaitcnts][NFC] Replace Wait.combined() with simple assignment (#179142)
Wait is initialized with all ~0s and by the time it reaches the updated
line it still holds the same value. So Wait.combined(AllZeroWait) is
effectively combining all ~0s with AllZeroWait and given that combined()
returns the min() of the two it should always return AllZeroWait.

So this patch replaces the assignment with `= AllZeroWait` to make it
easier to read.
2026-02-02 13:50:26 -08:00
vporpo
8b3b0b869e
[AMDGPU][SIInsertWaitcnt][NFC] Replace if/else with switch (#178956)
This is an NFC patch that replaces the consecutive ifs and else ifs in
generateWaitcntInstBefore() with a switch. This makes it a bit easier to
read.
2026-02-01 13:13:01 -08:00
vporpo
ef720acad0
[AMDGPU][SIInsertWaitcnts][NFC] Use loop to set Wait entries (#178764)
Please note that the original code was skipping STORE_CNT but this one
is not.
2026-01-30 16:18:03 -08:00
vporpo
c5862719c5
[AMDGPU][SIInsertWaitcnts][NFC] Introduce WaitEventSet container for events (#178511)
Before this patch WaitEventType events used to be collected in unsigned
integers that were used as small bit vectors.

This patch introduces a WaitEventSet container class to replace the
integer bit vectors with a class that hides the implementation of common
operations like insertion, removal, union, intersection etc. from the
user.

The WaitEventSet API matches that of a set and not a vector because we
don't care about the order of its contents. Internally though it is
still a bit vector that uses an unsigned integer as its storage, just
like the original implementation.

This patch should not change the functionality.
2026-01-30 08:55:44 -08:00
Jay Foad
7deea9db70
[AMDGPU] Move WaitcntBrackets::simplifyXcnt near other simplify functions. NFC. (#178673) 2026-01-29 15:49:11 +00:00
vporpo
2615005982
[AMDGPU][SIInsertWaitcnts] Cleanup: Remove WaitEventMaskForInst member variable (#178030)
The event mask is constant and target dependent it should be accessed
through the WCG object.
2026-01-28 12:22:48 -08:00
Jay Foad
775f02521d
[AMDGPU] Fix buggy insertion of DEALLOC_VGPRS message (#178401)
We inserted the DEALLOC_VGPRS message if there were no pending scratch
stores the first time an S_ENDPGM instruction was visited. But because
this pass uses a worklist to revisit blocks until it reaches a fixed
point, it is possible that pending scratch stores are only discovered on
the second or later visit to a block. Fix this by storing a flag for
each S_ENDPGM instruction which can be updated by later visits.
2026-01-28 13:29:26 +00:00
vporpo
89e38d65d8
[AMDGPU][SIInsertWaitcnts][NFC] Move static array definition (#178014)
Move the array out of the member function.
2026-01-26 11:21:20 -08:00
vporpo
8805e27365
[AMDGPU] Cleanup: Use unique_ptr for WCG and remove unnecessary class members (#177689) 2026-01-26 10:10:35 -08:00
Christudasan Devadasan
cf25346dcb
[AMDGPU][GFX1250] Optimize s_wait_xcnt for back-to-back atomic RMWs (#177620)
This patch optimizes the insertion of s_wait_xcnt instruction for
sequences of atomic read-modify-write (RMW) operations in the
SIInsertWaitcnts pass. The Memory Legalizer conservatively inserts a
soft xcnt instruction before each atomic RMW operation as part of PR
168852, which is correct given the nature of atomic operations.
However, for back-to-back atomic RMWs, only the first s_wait_xcnt is
necessary for better runtime performance. This patch tracks atomic
RMW blocks within each basic block and removes redundant soft xcnt
instructions, keeping only the first wait in each sequence. An atomic
RMW block continues through subsequent atomic RMWs and non-memory
instructions (e.g., ALU operations) but is broken by CU-scoped memory
operations, atomic stores, or basic block boundaries.
2026-01-24 08:21:41 +05:30
Shilei Tian
02d34a76f7
[NFCI][AMDGPU] Remove more redundant code from GCNSubtarget.h (#177297)
We are getting pretty close to use `GET_SUBTARGETINFO_MACRO` in the
header with this cleanup.
2026-01-22 09:07:15 -05:00
Jay Foad
2b522e0b09
Reapply "[AMDGPU] Fix excessive stack usage in SIInsertWaitcnts::run (#134835)" (#174215) (#177338)
This reverts commit 0dd03598dca91c93c74b94a714c38a4ffad0ed1c.

Apparently the stack usage on Windows was still large enough to cause
problems for some DirectX games.
2026-01-22 11:25:08 +00:00
Shilei Tian
1843a7fe9f
[NFCI][AMDGPU] Use X-macro to reduce boilerplate in GCNSubtarget.h (#176844)
`GCNSubtarget.h` contained a large amount of repetitive code following
the pattern `bool HasXXX = false;` for member declarations and `bool
hasXXX() const { return HasXXX; }` for getters. This boilerplate made
the file unnecessarily long and harder to maintain.

This patch introduces an X-macro pattern `GCN_SUBTARGET_HAS_FEATURE`
that consolidates 135 simple subtarget features into a single list. The
macro is expanded twice: once in the protected section to generate
member variable declarations, and once in the public section to generate
the corresponding getter methods. This reduces the file by approximately
600 lines while preserving the exact same API and functionality.
Features with complex getter logic or inconsistent naming conventions
are left as manual implementations for future improvement.

Ideally, these could be generated by TableGen using
`GET_SUBTARGETINFO_MACRO`, similar to the X86 backend. However,
`AMDGPU.td` has several issues that prevent direct adoption: duplicate
field names (e.g., `DumpCode` is set by both `FeatureDumpCode` and
`FeatureDumpCodeLower`), and inconsistent naming conventions where many
features don't have the `Has` prefix (e.g., `FlatAddressSpace`,
`GFX10Insts`, `FP64`). Fixing these issues would require renaming fields
in `AMDGPU.td` and updating all references, which is left for future
work.
2026-01-21 15:29:09 -05:00
Pankaj Dwivedi
6b86e24ec1
[AMDGPU][SIInsertWaitcnt] Address review feedback for waitcnt profiling expansion (#175922) 2026-01-17 14:57:45 +05:30
Ramkumar Ramachandra
d69335bac9
[LLVM] Clean up code using [not_]equal_to (NFC) (#175824)
Use llvm::[not_]equal_to landed in d2a521750 ([ADT] Introduce
bind_{front,back}, [not_]equal_to, #175056) across LLVM for cleaner
code.
2026-01-13 21:19:39 +00:00
hidekisaito
a062249932
[AMDGPU] Add DS loop waitcnt optimization for GFX12+ (#172728)
Add support for flushing DS_CNT in loop preheaders when the loop uses
values that were DS-loaded outside the loop. This is similar to the
existing VMEM loop optimization.

Assisted-by: Cursor / claude-4.5-opus-high
2026-01-12 13:34:02 -08:00
Jay Foad
27074aa31a
[AMDGPU] Fix crash in SIInsertWaitcnts debug output (#175518)
In some cases we were accessing `OldWaitcntInstr.getParent()->end()`
after `OldWaitcntInstr` had already been erased from its parent.
2026-01-12 14:48:53 +00:00
Jay Foad
3b2d14ba1c
[AMDGPU] Inline two helpers in SIInsertWaitcnts. NFC. (#174557) 2026-01-12 14:26:31 +00:00
Pankaj Dwivedi
3dfb782333
[AMDGPU][SIInsertWaitcnt] Implement Waitcnt Expansion for Profiling (#169345)
Reference issue: https://github.com/ROCm/llvm-project/issues/67

This patch adds support for expanding s_waitcnt instructions into
sequences with decreasing counter values, enabling PC-sampling profilers
to identify which specific memory operation is causing a stall.

This is controlled via:
Clang flag: -mamdgpu-expand-waitcnt-profiling /
-mno-amdgpu-expand-waitcnt-profiling
Function attribute: "amdgpu-expand-waitcnt-profiling"

When enabled, instead of emitting a single waitcnt, the pass generates a
sequence that waits for each outstanding operation individually. For
example, if there are 5 outstanding memory operations and the target is
to wait until 2 remain:


**Original**: 
s_waitcnt vmcnt(2)

**Expanded**:  
s_waitcnt vmcnt(4)
s_waitcnt vmcnt(3)
s_waitcnt vmcnt(2)

The expansion starts from (Outstanding - 1) down to the target value,
since waitcnt(Outstanding) would be a no-op (the counter is already at
that value).

- Uses ScoreBrackets to determine the actual number of outstanding
operations
- Only expands when operations complete in-order
- Skips expansion for mixed event types (e.g., LDS+SMEM on same counter)
- Skips expansion for scalar memory (always out-of-order)

Releated previous work for Reference
- **PR**: llvm/llvm-project#79236 (related `-amdgpu-waitcnt-forcezero`)

---------

Co-authored-by: Pierre van Houtryve <pierre.vanhoutryve@amd.com>
2026-01-12 17:35:06 +05:30
Jay Foad
475f022cb7
[AMDGPU] Add support for GFX12 expert scheduling mode 2 (#170319) 2026-01-09 15:49:10 +00:00
Jay Foad
0494abbea0
[AMDGPU] Make WaitcntBrackets::simplifyWaitcnt const again (#173390)
The original design was:
- WaitcntBrackets::simplifyWaitcnt(Wait) updates Wait based on the
  current state of WaitcntBrackets, removing unnecesary waits.
- WaitcntBrackets::applyWaitcnt(Wait) updates WaitBrackets based on
  Wait, updating the state by applying the specified waits.

This was changed by #164357 which started calling applyWaitcnt from
simplifyWaitcnt.

This patch restores the original design without any significant
functional changes. There is some code duplication because both
simplifyWaitcnt and applyWaitcnt need to understand how XCNT interacts
with other counters like LOADCNT and KMCNT.
2026-01-05 13:34:32 +00:00
Jay Foad
b3c3e5fd99
[AMDGPU] Simplify and document waitcnt handling on call and return (#172453)
Start documenting the ABI conventions for dependency counters on
function call and return.

Stop pretending that SIInsertWaitcnts can handle anything other than the
default documented behavior.
2026-01-05 13:29:54 +00:00
Jay Foad
0dd03598dc
Revert "[AMDGPU] Fix excessive stack usage in SIInsertWaitcnts::run (#134835)" (#174215)
This reverts commit 008c875be85732f72c4df4671167f5be79f449eb.

PR #162077 / #171779 shrunk the WaitcntBrackets class by using DenseMaps
instead of large arrays, so the size of a temporary WaitcntBrackets
allocated on the stack is no longer a concern.

With this patch on Linux I measured the stack size of
SIInsertWaitcnts::run increasing from 456 bytes to 632 bytes.
2026-01-05 12:10:11 +00:00