This is an archive of the discontinued LLVM Phabricator instance.

[llvm-mca] Add a HardwareUnit and Context classes.
ClosedPublic

Authored by mattd on Jun 27 2018, 5:20 PM.

Details

Summary

This patch moves the construction of the default backend from llvm-mca.cpp and into mca::Context. The Context class is responsible for holding ownership of the simulated hardware components. These components are subclasses of HardwareUnit. Right now the HardwareUnit is pretty bare-bones, but eventually we might want to add some common functionality across all hardware components, such as isReady() or something similar.

I have a feeling this patch will probably need some updates, but it's a start. One thing I am not particularly fond of is the rather large interface for createDefaultPipeline. That convenience routine takes a rather large set of inputs from the llvm-mca driver, where many of those inputs are generated via command line options.

One item I think we might want to change is the separating of ownership of hardware components (owned by the context) and the pipeline (which owns Stages). In short, a Pipeline owns Stages, a Context (currently) owns hardware. The Pipeline's Stages make use of the components, and thus there is a lifetime dependency generated. The components must outlive the pipeline. We could solve this by having the Context also own the Pipeline, and not return a unique_ptr<Pipeline>. Now that I think about it, I like that idea more.

Diff Detail

Repository
rL LLVM

Event Timeline

mattd created this revision.Jun 27 2018, 5:20 PM

Great, only a few nits.

tools/llvm-mca/Context.cpp
30 ↗(On Diff #153213)

The comment is already on the declaration. I think you can remove it here.

tools/llvm-mca/Context.h
12 ↗(On Diff #153213)

I don;t see any such "utility routines" for now. Remove ?

tools/llvm-mca/HardwareUnit.h
25 ↗(On Diff #153213)

[nit] Let's make this the class anchor.

mattd updated this revision to Diff 153749.Jul 2 2018, 10:06 AM
mattd marked 2 inline comments as done.
  • Removed a comment.
  • Pinned the HardwareUnit's vtable in HardwareUnit.cpp
mattd added a comment.Jul 2 2018, 10:07 AM

Thanks for the review @courbet!

tools/llvm-mca/Context.cpp
30 ↗(On Diff #153213)

Gotcha. I'll remove it.

tools/llvm-mca/Context.h
12 ↗(On Diff #153213)

I was considering createDefaultPipeline a "utility routine'." I plan on adding another, similar, utility routine shortly.

tools/llvm-mca/HardwareUnit.h
25 ↗(On Diff #153213)

Good call. Thanks for the suggestion. I went ahead and added an 'anchor' method instead of pinning the dtor. We already added an explicit anchor to HWEventListener.

Hi Matt,

Thanks for the patch. See my comments below:

tools/llvm-mca/Context.h
11–13 ↗(On Diff #153749)

We should be consistent with the terminology. I suggest to use hardware unit instead of hardware component.

38 ↗(On Diff #153749)

s/addHardware/addHardwareUnit

44–48 ↗(On Diff #153749)

I was wondering whether we should have a PipelineOptions struct which encapsulates all the unit options. The factory method createDefaultPipeline would take a PipelineOptions as input; that would simplify the argument list.

tools/llvm-mca/HardwareUnit.h
11–12 ↗(On Diff #153749)

Hardware units.

25 ↗(On Diff #153213)

Can we avoid adding method anchor()? You should be able to define the destructor in the .cpp file.

tools/llvm-mca/llvm-mca.cpp
499–502 ↗(On Diff #153749)

I think the Context should be created only once, and then reused by every CodeSnippet. The Context should be the same for every CodeSnippet.

mattd updated this revision to Diff 153801.Jul 2 2018, 2:38 PM
mattd marked 5 inline comments as done.
  • Pinned HardwareUnit's vtable using the dtor.
  • Updated the text to refer to "unit" instead of "component" in certain places.
  • Moved the Context construction outside of the code-region loop.
mattd added a comment.Jul 2 2018, 2:38 PM

Thanks for the review @andreadb!

andreadb added inline comments.Jul 3 2018, 4:05 AM
tools/llvm-mca/Context.h
12–13 ↗(On Diff #153801)

Maybe be more specific here, and say that it provides a method to instantiate a "default" dispatch/execute/retire pipeline.
We can always update this comment in future.

44–48 ↗(On Diff #153749)

I still think that - for simplicity and readability - we should wrap all those flags into a PipelineOptions struct.

We don't need to pass a MCSchedModel to createDefaultPipeline because we can always query STI to obtain it.

Even better, we can have that MCSubtargetInfo and MCRegisterInfo are passed in input to the constructor of Context, and used internally by its "utility" methods.

If we do all of this, then the createDefaultPipeline() would simply take a PipelineOptions, a SourceMgr& and a InstrBuilder&.

mattd updated this revision to Diff 153945.Jul 3 2018, 11:35 AM
  • Updated the Context{.h,cpp} comment to be a bit more specific about what 'utility' routines it possesses.
  • Added a mca::PipelineOptions for simplifying the creation of the default out-of-order pipeline.
mattd updated this revision to Diff 153946.Jul 3 2018, 11:42 AM
  • Made SrcMgr a required argument for constructing a default pipeline.
mattd added inline comments.Jul 3 2018, 11:48 AM
tools/llvm-mca/Context.h
33 ↗(On Diff #153946)

I not sure if we want to have the PipelineOptions struct nested within the Context class or not. I'm unbiased to either decision, and felt that exposing it as part of the root mca namespace isn't a bad decision.

44–48 ↗(On Diff #153749)

That's cool with me. We will definitely need to make SourceMgr a required input to createDefaultPipeline. I made InstrBuilder a member of the PipelineOptions structl; we only ever construct that item once in llvm-mca, outside of the region generation loop.

andreadb accepted this revision.Jul 4 2018, 2:46 AM

LGTM if you address the comments below.

Thanks.

tools/llvm-mca/Context.h
33 ↗(On Diff #153946)

I think it is fine either way.

46–48 ↗(On Diff #153946)

These last three fields are not really "options".
STI and MRI should never change, and those can be safely added to the context, and initialized at construction time.
The InstrBuilder can be passed in input to the call to createDefaultPipeline().
We can change this design in future if we see that there are better designs.

This revision is now accepted and ready to land.Jul 4 2018, 2:46 AM
mattd marked an inline comment as done.Jul 6 2018, 9:43 AM

Thanks @andreadb. I like your suggestions. I will make them, run some tests, and land the patch.

This revision was automatically updated to reflect the committed changes.