From: Jin Ma <[email protected]>
To: Jeff Law <[email protected]>
Cc: gcc-patches <[email protected]>
Subject: Re: [PATCH v5 19/22] RISC-V: Add load/store macro-fusion scheduling
priorities
Hi Jeff,
> On 9/2/26 7:26 AM, Jin Ma wrote:
> >>
> > Thank you for the further clarification.
> >
> > TARGET_SCHED_FUSION_PRIORITY receives only one instruction per call, so
> > it cannot directly ask whether two specific instructions can fuse. I
> > am trying to find a better approach that covers these different designs
> > without duplicating microarchitectural constraints.
> Understood. Unfortunate, but that's just how things are.
>
> >
> > One simple idea is to split the decision into two levels. The first
> > level would be used by the priority hook. Since that interface sees
> > only one instruction at a time, it would determine only whether the
> > instruction could belong to an enabled fusion operation for the current
> > tune. This single-instruction eligibility check could be parameterized
> > by the operation and handle properties already known at that point,
> > such as load versus store, integer versus floating-point register file,
> > access mode and width, address form, and extension type. It would not
> > try to determine relationships between two instructions.
> >
> > The second level would be used where both candidate instructions are
> > available. It would call the complete fusion matcher to check actual
> > pair constraints, such as a common base, adjacent offsets, increasing
> > or decreasing order, pair alignment, and register relationships. To
> > avoid maintaining two sets of rules that could drift apart, the
> > priority classification and final matcher could share the same
> > operation-specific single-instruction eligibility check, with the full
> > matcher adding only the constraints between the two instructions.
> >
> > This would allow Veyron V2, C950, and ARC-V to retain their respective
> > access-width and other restrictions without applying the restrictions
> > of one design globally to the others. Existing fusion operations would
> > be reused where they can express the required behavior, and a new
> > definition would be added only when an important difference cannot be
> > represented otherwise. This idea is not final yet. I will continue
> > checking whether it can support these three designs cleanly and share
> > the common logic with Michiel's implementation.
> >
> > I am not sure whether this accurately reflects your suggestion. Do you
> > have any further comments or guidance?
> I think this starts to look at lot like the existing ARM code to convert
> adjacent loads into load pairs (and similarly for stores), much like
> Andrew also noted. It happens to be the case that I'm starting to
> ponder how fusions are going to work for Qualcomm designs going forward
> and the ARM approach seems like the best fit.
>
> Essentially we don't have a data dependency to help us identify what
> loads (or stores) should be investigated as a potential for load
> pairing. With your suggestion I think we end up marking just about
> every load in practice on some designs -- at which point, why bother
> with the first phase at all.
>
> Jeff
>
>
> >
> > Thanks,
> > Jin
Even if most loads pass the eligibility checks on some designs, I think
retaining the first phase may still have some value. This is only a very
preliminary thought. In the implementation, this check is part of the
existing priority hook's priority calculation. It calls a shared helper
to check each instruction's eligibility, without adding a separate pass
to mark candidates. It uses the current tune's fusion mask and shared
rules for memory pairs, so the priority hook and the full matcher use
the same eligibility conditions. For designs expressible by these rules,
vendors can select the enabled operations and maintain the necessary
constraints in one place. This can reduce duplicated logic and the risk
of updating only one of the callers.
For example, C9501's integer load-pair fusion operations do not support
lb or lh, so the eligibility check excludes them. The ARC-V design
Michiel described supports fusing loads of 2 or 4 bytes, but not 8
bytes. Rules expressing those restrictions could admit accesses of 2
bytes such as lh and exclude ld. This would keep each design's
restrictions in its own rules.
My understanding is that TARGET_SCHED_FUSION_PRIORITY is intended to
guide grouping and ordering during scheduling. For eligible
instructions, the hook computes fusion_pri from the register file,
load/store kind, mode and base, and then computes pri within the group
from the offset and the supported direction. Even if many loads pass the
eligibility checks, this grouping and ordering may still help. For
example, on a design that supports fusing loads of 8 bytes in decreasing
address order, these independent instructions:
ld a1,0(a0)
add a3,a4,a5
ld a2,8(a0)
These priorities can encourage the scheduler to arrange them as follows:
ld a2,8(a0)
ld a1,0(a0)
add a3,a4,a5
Movement remains constrained by the scheduler's dependency analysis. The
full matcher checks the common base, adjacent offsets, alignment and
register relationships required for an actual pair. This grouping and
ordering is a scheduling heuristic; it does not establish that every
candidate has a fusible partner. A candidate can pass the eligibility
check but still fail to fuse because the offsets are not adjacent or
other pair constraints are not satisfied. Searching explicitly for
fusion partners is still worth investigating.
My intention is to use the existing hook for the grouping and ordering
above, as a relatively small scheduling improvement. If you consider
this approach unsuitable, see shortcomings in its design, or think it
would be better to handle this directly through pair-fusion, we can set
this patch aside despite its small scope and pursue that direction in
later work :)
I can later investigate a RISC-V implementation of the pair-fusion pass
and evaluate its benefits. If it shows a clear benefit, I will try to
prepare a patch for review.
Thanks,
Jin