This is an archive of the discontinued LLVM Phabricator instance.

[SampleFDO][NFC] Refactor: make SampleProfileLoaderBaseImpl a template class
ClosedPublic

Authored by xur on Feb 18 2021, 11:34 AM.

Details

Summary

This patch makes SampleProfileLoaderBaseImpl a template class so it can be
used in CodeGen transformation.

Noticeable changes:

  • use one template parameter and use a typemap to get other used types.
  • use a wrapper function getFunction to get IR level function.
  • use a wrapper function getEntryBB to get first BB as MachineBasicBlock does not have this API.
  • remove the temporary "inline" keywords in previous refactor patch.
  • change the template function findEquivalencesFor to a regular function. This function has a single caller with type of PostDominatorTree. It's simpler to use the type directly because MachinePostDominatorTree is not a derived type of template DominatorTreeBase.

Diff Detail

Event Timeline

xur created this revision.Feb 18 2021, 11:34 AM
xur requested review of this revision.Feb 18 2021, 11:34 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 18 2021, 11:34 AM

Really really broad feedback - this work to write common abstractions over LLVM IR and MIR seems to overlap with https://lists.llvm.org/pipermail/llvm-dev/2020-December/147433.html

It's non-trivial as to what exactly these APIs should look like (virtual/type erased v templates, etc). But may be useful to consider some of the options here.

My current rough guess is that templates are probably the right tool, but that more common abstractions should be implemented in the IR types themselves - eg: the TypeMap and getFunction/getEntryBB could be rolled into the IR types themselves as authoritative/core features, rather than grafting them on with traits.

llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
50–71

Seems like a layering violation to be declaring these entities that aren't reachable from Transform/Utils?

Could the MIR TypeMap specialization be defined in the MIR library instead?

63

This should probably be a declaration (it should mean more immediate/explicit compilation failures):

template<typename BlockT> struct TypeMap;

(also I tend to suggest using typename rather than class - since they don't have any different meaning for C++ and typename more accurately describes what kind of entity can be used (though, yes, in this particular case the typenames do have to be classes))

llvm/lib/Transforms/IPO/SampleProfile.cpp
221–234

Perhaps these functions could be part of the TypeMap? (Generalizing TypeMap to "IRTraits" or something like that)

Alternatively they could be implemented as overloads, but part of traits is probably the right call.

xur added a comment.Feb 18 2021, 4:21 PM

Really really broad feedback - this work to write common abstractions over LLVM IR and MIR seems to overlap with https://lists.llvm.org/pipermail/llvm-dev/2020-December/147433.html

It's non-trivial as to what exactly these APIs should look like (virtual/type erased v templates, etc). But may be useful to consider some of the options here.

My current rough guess is that templates are probably the right tool, but that more common abstractions should be implemented in the IR types themselves - eg: the TypeMap and getFunction/getEntryBB could be rolled into the IR types themselves as authoritative/core features, rather than grafting them on with traits.

David. Thanks for the comments!

Yes. If all the building blocks have a common obstructions, we probably can use other method to share the common transformation / analysis code b/w IR and MIR.
This template base method has been used in the code base (such as BlockFreqInfo, Dominator and DominatorFrontier).
For now, I think I will use the template base method as I have some other patches depending on this.

Once the common abstractions are in-place. I don't mind to refactor the code again if that is a better way for sharing the code.

xur added inline comments.Feb 18 2021, 4:33 PM
llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
50–71

why this is a layering violation? I think this is just a forward declaration -- we don't need the definition (complete type) here.

63

TypeMap specialization needs to after the TypeMap definition, but before the uses of the types.
That means I need to put the code in header, and split line 63 to a common header files.
I think that is a littler messy than current way.

using typename is a good idea. I will change.

llvm/lib/Transforms/IPO/SampleProfile.cpp
221–234

I did not put into the TypeMap (or IRTraits) is because in current implementation, we don't have the complete type of the type parameters.
If we put these functions into traits, we need to expose the definition.

dblaikie added inline comments.Feb 18 2021, 7:19 PM
llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
50–71

While it wouldn't break any build system I know about - it would break, for instance, in C++ standard modules (where declarations are owned by the module that declares them) and violates at least conceptual layering, that Transforms have nothing to do with MIR.

(Google's style guide talks about not forward declaring entities not in the same project - though what constitutes a "project" is a bit vague and probably doesn't quite apply here)

63

TypeMap specialization needs to after the TypeMap definition, but before the uses of the types.

I don't think that's the case. At least a small test case ( https://godbolt.org/z/ecjox8 ) appears to work as desired - and I'd expect /something/ like that to work, since it'd be quite common to specialize a template far away from where that template is defined and used, since it might need to be specialized with some type unknown to the template and the usage (as is/should be the case here).

xur added inline comments.Feb 19 2021, 9:51 AM
llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
50–71

Thanks for the explanation. Good to know this!

63

Sorry that I did not make my point clear. I know the small test would work -- as it does have the problem I was talking about.

The "TypeMap definition" is like line 1 in the small test case. It needs to be before the specialization at line 4 and line 12.
In my code, line 4 and line 12 will be in a different header file (or I can keep one in the template header, but the other will go the MIR header).
This MIR header file need to be before the template header file. But line 1 needs to be before the MIR header file.
So line 1 needs to be moved from the template header -- so that it appears before line 4 and line 12.

But this is not a problem. Because the layer violation issue, I need to change it anyway.

xur updated this revision to Diff 325028.Feb 19 2021, 10:14 AM

Integrated the comments from David Blaikie.

dblaikie added inline comments.Feb 19 2021, 12:40 PM
llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
63

Sorry I'm not quite following.

Why would the MIR header file need to go before the template header file? In my example, all the MIR related things (struct b, and traits<b> specialization) came after the generic template/IR things.

I think the declaration of TypeMap/IRTraits could remain in SampleProfileLoaderBaseImpl.h for now.

xur marked an inline comment as done.Feb 19 2021, 2:48 PM
xur added inline comments.
llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
63

ah. OK. you are right!
I got the point now.

I will update the patch shortly.

xur updated this revision to Diff 325097.Feb 19 2021, 2:56 PM
xur marked an inline comment as done.

Integrated David's review comments.

dblaikie accepted this revision.Feb 19 2021, 3:10 PM

Looks good, thanks!

llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
52

This can be reduced to a declaration - might make for better compilation errors if the template is used without a specialization.

This revision is now accepted and ready to land.Feb 19 2021, 3:10 PM
xur added inline comments.Feb 19 2021, 3:45 PM
llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
52

Good point. Will change to a declaration.

hoy accepted this revision.Feb 22 2021, 12:26 PM

We have an MCF-based counts inference algorithm to be integrated into the refactored framework later. The algorithm only works on IR so far since it leverages certain IR characteristics like Unreachable and Invoke instructions to distribute counts more reasonably. Looks like some sort of specialized code is needed. So far the refactoring looks good to me. Thanks.

wmi accepted this revision.Feb 22 2021, 10:20 PM

LGTM.