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.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
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? |
- 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.
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 ... |
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; ... |
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; ... }; |
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. |
- 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.
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. |
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp | ||
---|---|---|
121 | Should the else case also do setInitialBits(TailFoldingOpts::Disabled);? |
There are several of these uint8_t flying round, which will make it awkward to change later. Perhaps worth using a typedef?