This is an archive of the discontinued LLVM Phabricator instance.

[AArch64][NFC] Refactor the tail-folding option
ClosedPublic

Authored by david-arm on May 2 2023, 8:40 AM.

Details

Summary

This patch does simple refactoring of the tail-folding
option in preparation for enabling tail-folding by
default for neoverse-v1. It adds a default tail-folding
option field to the AArch64Subtarget class that can
be set on a per-CPU.

Diff Detail

Event Timeline

david-arm created this revision.May 2 2023, 8:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 2 2023, 8:40 AM
david-arm requested review of this revision.May 2 2023, 8:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 2 2023, 8:40 AM
sdesmalen added inline comments.May 9 2023, 2:45 AM
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
43–94

There is probably little value in having the copied std::string here with a SmallVector of StringRefs for the comma-separated options. If you're re-parsing the string each time to query what options are set, then you can just as well split the original StringRef TailFoldingOptionLoc at that point and make SmallVector<StringRef> TailFoldTypes local to the parsing function.

96

I'm still not entirely happy with the concept of having to re-parse the full string every time this information is queried, but if that only happens very irregularly, I guess the overhead is only minimal.

Just as a suggestion, one thing you could do is to parse the string for the reductions/recurrences/reverse early on and store that in a EnableBits + DisableBits mask, and have this separate from parsing of simple/disabled/all/default. Then, at the point of querying the tail folding options, you can do something like:

uint8_t InitialBits = ... // either all zero, all ones, or SimpleBits or DefaultBits (queried from the target)
Bits = (InitialBits | EnableBits) ^ DisableBits;

It does mean that it would not be allowed to have a string such as reductions+default, because default/all/disabled/simple all need to come before the other toggle on/off options. Also, it might make make sense to also make it illegal to write disabled+simple+all because only one of those options should be set.

This way the syntax would become:

(disabled|all|default|simple)[+(reductions|recurrences|reverse|noreductions|norecurrences|noreverse)]*
3561–3562

I find this interface a little confusing and wonder if instead you can make TailFoldingOptionLoc a std::string, and then do:

TailFoldingOption Opt(TailFoldingOptionLoc, ST->getSVETailFoldingDefaultOpts());
return Opt.satisfies(Required);

What do you think?

david-arm updated this revision to Diff 520966.May 10 2023, 6:11 AM
  • Refactored TailFoldingOption class to parse the string at the time of assignment and keep a record of the InitialBits, EnableBits and DisableBits. This requires changing the semantics of the option to require only one of (disabled|all|simple|default), which must also be the first in the list.
david-arm marked 2 inline comments as done.May 10 2023, 6:14 AM
david-arm added inline comments.
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
96

I've tried to implement your suggestion as best I can!

3561–3562

Now that we no longer parse the string each time, I'm not sure if it still makes sense to refactor this way? I could in theory create a small, new wrapper class with a different name just so I can pass in the option, but wasn't sure if it was worth the extra code?

Thanks for refactoring this @david-arm, this seems like a step in the right direction.

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
42–43

nit: All members of a class are private by default, so you can remove this.

43–94

Can you add a comment explaining why these are required?

46–48

Can you make this part of the constructor? e.g.

TailFoldingOption(bool NeedsDefault = true) { ... }
TailFoldingOption(uint8_t InitBits) { ... }

When you make NeedsDefault = true the default, then you can do away with:

if (Val.empty()) {
  setNeedsDefault();
  return;
}

in operator=

110

Could you split the parsing in two steps, such that you first parse only the "disabled|all|simple|default", and only then start iterating the individual toggles, e.g.

if (TailFoldTypes[0] == "disabled")
  ...
else if (TailFoldTypes[0] == "all")
  ...
else if (TailFoldTypes[0] == "simple")
  ...
else if (TailFoldTypes[0] == "default")
  ...
else
  report_fatal_error(..)

for (auto TailFoldType : ArrayRef<StringRef>(TailFoldTypes).drop_front()) {
  if (TailFoldType == "reductions")
    setEnableBit(TFReductions);
  ...
}
llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
542

nit: Can you put this in a namespace, e.g.

namespace TailFoldingOpts {
  enum TailFoldingOptsImpl : uint8_t {
    Disabled = 0x00;
    Simple = 0x01;
    ...
  };
};

That makes it a bit easier to use these, e.g.

TailFoldingOpts::Disabled
TailFoldingOpts::Simple
...
paulwalker-arm added inline comments.May 12 2023, 3:12 AM
llvm/lib/Target/AArch64/AArch64Subtarget.h
131

There are several of these uint8_t flying round, which will make it awkward to change later. Perhaps worth using a typedef?

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
96

I think the modern way to do this is inline with the variable definitions, i.e

uint8_t InitialBits = 0;
...
paulwalker-arm added inline comments.May 12 2023, 3:15 AM
llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
542

The modern way to do this is via an enum class?, i.e.

enum class TailFoldingOpt : uint8_t {
  Disabled = 0x00;
  Simple = 0x01;
  ...
};
david-arm updated this revision to Diff 522207.May 15 2023, 8:28 AM
david-arm marked 4 inline comments as done.
  • Address various review comments involving refactoring code.
david-arm marked 3 inline comments as done.May 15 2023, 8:31 AM

I've tried to address the various comments on the patch and maintain the existing functionality!

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
46–48

I don't think this helps because the constructor never gets invoked in any other way except the default TailFoldingOption(). The only time this ever gets set to something other than default values is when setting the option value, which occurs in operator=.

I've changed this code

if (Val.empty()) {
  setNeedsDefault();
  return;
}

to now emit an error because if the user has supplied the option "-msve-tail-folding=" I think we should treat that as user error.

llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
542

This turns out to be a huge pain because it prevents casting between the type and an integer. I tried also using LLVM_DECLARE_ENUM_AS_BITMASK, which didn't stop the compiler complaining. :)

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
119–120

As discussed offline I'd rather keep the existing ability to specify the individual options manually (i.e. -sve-tail-folding=reductions+reverse...), which is more natural than forcing the user to first switch everything off before selectively turning options back on.

llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
546

Is Disabled used anywhere? If not then I think it's best removed.

Matt added a subscriber: Matt.May 15 2023, 3:03 PM
david-arm updated this revision to Diff 522497.May 16 2023, 1:54 AM
  • Removed a reportError when parsing the first option as we want to permit the user doing stuff like -sve-tail-folding=reductions.
  • Changed TailFoldingOpts to be an enum class.
david-arm marked 3 inline comments as done.May 16 2023, 1:56 AM
david-arm added inline comments.
llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
542

Thanks for help with this @paulwalker-arm! I've now changed this to be an enum class.

546

It is required now that TailFoldingOpts is an enum class I think.

paulwalker-arm accepted this revision.May 16 2023, 3:00 AM
paulwalker-arm added inline comments.
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
121

Should the else case also do setInitialBits(TailFoldingOpts::Disabled);?

This revision is now accepted and ready to land.May 16 2023, 3:00 AM
This revision was landed with ongoing or failed builds.May 17 2023, 1:39 AM
This revision was automatically updated to reflect the committed changes.
david-arm marked an inline comment as done.
david-arm marked an inline comment as done.May 17 2023, 1:50 AM