This is an archive of the discontinued LLVM Phabricator instance.

[llvm-mca] Refactor event listeners to make the backend agnostic to event types.
ClosedPublic

Authored by courbet on Mar 9 2018, 8:48 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

courbet created this revision.Mar 9 2018, 8:48 AM

Thanks Clement.

Please run clang-format on the patch. I found that the code was not correctly formatted in several places.
See my comments below.

tools/llvm-mca/Backend.h
85 ↗(On Diff #137767)

80-col.

tools/llvm-mca/BackendStatistics.cpp
24–36 ↗(On Diff #137767)

clang-format.

tools/llvm-mca/BackendStatistics.h
120–121 ↗(On Diff #137767)

Remove this change. Alternatively, run clang-format on this file.

122–123 ↗(On Diff #137767)

clang-format.

tools/llvm-mca/Dispatch.cpp
154–160 ↗(On Diff #137767)

80-col.

tools/llvm-mca/HWEventListener.h
24 ↗(On Diff #137767)

We need a better (doxygen) comment here.

27 ↗(On Diff #137767)

Could you please explain what is the long term goal? Do you plan to remove this EventType?

42 ↗(On Diff #137767)

Period at end of sentence.

tools/llvm-mca/ResourcePressureView.cpp
48–50 ↗(On Diff #137767)

You don't need braces here.

tools/llvm-mca/ResourcePressureView.h
62 ↗(On Diff #137767)

Why this change?

tools/llvm-mca/Scheduler.h
457–458 ↗(On Diff #137767)

Is the plan to remove this dependency in the long term?

RKSimon added a subscriber: RKSimon.

Some minor style comments

tools/llvm-mca/Backend.h
85 ↗(On Diff #137767)

Add an assertion before dereferencing pointer?

tools/llvm-mca/HWEventListener.h
52 ↗(On Diff #137767)

UsedResources(UsedResources) ? scary - don't name arguments the same as class members

tools/llvm-mca/Scheduler.h
489 ↗(On Diff #137767)

Avoid the same name for a argument as a member.

courbet updated this revision to Diff 137980.Mar 12 2018, 3:32 AM
courbet marked 12 inline comments as done.
  • clang-format
  • more doc

Thanks, PTAL.

tools/llvm-mca/HWEventListener.h
24 ↗(On Diff #137767)

oops.

27 ↗(On Diff #137767)

I've given it a shot, tell me what you think.

tools/llvm-mca/Scheduler.h
457–458 ↗(On Diff #137767)

Not really. If we want the Backend class to be agnostic to the pipeline structure, we need inter-component dependencies to be carried by the component themselves. The pipeline creation function (in the subtarget, see https://reviews.llvm.org/D43951?id=136547#inline-384507) should be the one that does that the plugging.

However it would be better if the DispatchUnit was given in the ctor, maybe through some wrapper object (but let's do that if the need arises).

courbet retitled this revision from [llvm-mca] Revactor event listeners to make the backend agnostic to event types. to [llvm-mca] Refactor event listeners to make the backend agnostic to event types..Mar 12 2018, 3:36 AM
andreadb added inline comments.Mar 12 2018, 5:19 AM
tools/llvm-mca/HWEventListener.h
30–35 ↗(On Diff #137980)

Thanks for the description.

In my view, all the enum values in EventType should be known by all targets. Those should be all known concepts. This would minimize the impact of a redesign on the current views. Targets could then extend this with custom event types.
We should probably find a better name for this enum. Something like 'BaseEventType' or 'GenericEventType'. Also, please add a 'LastGenericEventType' enum value at the end.

70 ↗(On Diff #137980)

s/simulator/backend pipeline

tools/llvm-mca/Scheduler.h
457–458 ↗(On Diff #137767)

Essentially - correct me if I am wrong - your plan is to make dependencies between components (i.e. pipeline stages) explicit. Each component knows who to notify/interact with (like in this case).
The advantage is that the Backend is now no longer responsible for orchestrating the execution. This allows the definition of a simpler Backend class which acts as a container of stages, and starts the execution. Components will know how to coordinate with each other (since they _explicitly_ know their position in the pipeline).

If my understanding is correct, then this design is still quite rigid, since components now explicitly know other componets of the pipeline. That being said, we can still achieve modularity by letting users define their custom 'DispatchUnit'/'Scheduler'(etc.) classes with (potentially) different dependencies.

Please could you share (i.e. add as a description to this review) your design and give us more details on how you plan to restructure this code? Modularity can be achieved in many different ways. I just want to make sure that we all agree with the final design. At the moment, it is still a bit unclear what you have in mind.

courbet marked an inline comment as done.Mar 12 2018, 6:30 AM
courbet added inline comments.
tools/llvm-mca/HWEventListener.h
30–35 ↗(On Diff #137980)

In my view, all the enum values in EventType should be known by all targets. Those should be all known concepts. This would minimize the impact of a redesign on the current views. Targets could then extend this with custom event types.

I fully agree. That's what I meant by "Of course some event types (e.g. Retired) can be shared among subtargets". Right now all the values in the enum apply to all subtargets, but as soon as the fonrtend is modelled, this won't be the case anymore (there are weird subtarget-specific things such as LCP stalls for Intel). I have made that clearer.

The point of the fixme was more about where this enum should be defined: I think eventually it should be in a base TD class that subtargets can extend. But that's not important right now.

We should probably find a better name for this enum.

Went for GenericEventType.

tools/llvm-mca/Scheduler.h
457–458 ↗(On Diff #137767)

Essentially - correct me if I am wrong - your plan is to make dependencies between components (i.e. pipeline stages) explicit. Each component knows who to notify/interact with (like in this case).

The advantage is that the Backend is now no longer responsible for orchestrating the execution. This allows the definition of a simpler Backend class which acts as a container of stages, and starts the execution. Components will know how to coordinate with each other (since they _explicitly_ know their position in the pipeline).

Exactly.

If my understanding is correct, then this design is still quite rigid, since components now explicitly know other components of the pipeline.

In the current design, there are two things that are actually hardcoded:
(1) - The pipeline structure itself. This is because the Backend class has a list of exact components that it manipulates through their exact types (not through a Component of PipelineStage interface). If a subtarget wants to add a new component with type MyComponent, we need to add a std::unique_ptr<MyComponent> to class Backend, and add plumbing to let MyComponent communicate its state changes with listeners.
(2) - Interaction between components. This is because the interaction between HWS and DU` happens in Backend. If a subtarget wants to add a component in between HWS and DU, it has to modify classes HWS, DU and Backend.

This patch:

  • Addresses the second part of (1): Components can emit new events, without changes to Backend.
  • Improves (2) a bit: you now only have to change HWS` and DU, and not Backend.

I was actually considering this patch more as a refactoring (I'm not really changing anything ) than a change of design, to allow me to present a suggested design more easily in a next patch.

That being said, we can still achieve modularity by letting users define their custom 'DispatchUnit'/'Scheduler'(etc.) classes with (potentially) different dependencies.

Exactly. And we should also reduce how much Scheduler and DispatchUnit have to know about each other.
In our approach, all a component has to know about the previous (resp. next) element in the pipeline is what type of elements it creates (resp. accepts): Instruction/Uop/InsertYourType. Nothing has to be known about what the component is or does. That means you can substitute any component for another in the piplene as long as it has the same input and output type, and you can add a component in the middle of the pipeline as long as it manipulates elements without changing their type.
Without going as far as this, the only way we can ensure that subtargets can reuse "generic" components is to abstract a bit the type of the components.

RKSimon added inline comments.Mar 12 2018, 10:26 AM
tools/llvm-mca/TimelineView.cpp
44 ↗(On Diff #137980)

Isn't this repeated at the end of the function?

courbet updated this revision to Diff 138132.Mar 13 2018, 12:13 AM
courbet marked an inline comment as done.

Remove redundant instruction.

andreadb accepted this revision.Mar 13 2018, 3:29 AM

Thanks Clement!

I only have one minor nit. Otherwise, the patch looks good to me.

-Andrea

tools/llvm-mca/HWEventListener.h
64 ↗(On Diff #138132)

UR should be a const ArrayRef.

This revision is now accepted and ready to land.Mar 13 2018, 3:29 AM
courbet updated this revision to Diff 138159.Mar 13 2018, 5:19 AM
courbet marked an inline comment as done.

rebase

Thanks !

tools/llvm-mca/TimelineView.cpp
44 ↗(On Diff #137980)

Indeed, thanks for the catch.

This revision was automatically updated to reflect the committed changes.