[Clang][AArch64] Support AArch64 target(..) attribute formats.

This adds support under AArch64 for the target("..") attributes. The
current parsing is very X86-shaped, this patch attempts to bring it line
with the GCC implementation from
https://gcc.gnu.org/onlinedocs/gcc/AArch64-Function-Attributes.html#AArch64-Function-Attributes.

The supported formats are:
- "arch=<arch>" strings, that specify the architecture features for a
  function as per the -march=arch+feature option.
- "cpu=<cpu>" strings, that specify the target-cpu and any implied
  atributes as per the -mcpu=cpu+feature option.
- "tune=<cpu>" strings, that specify the tune-cpu cpu for a function as
  per -mtune.
- "+<feature>", "+no<feature>" enables/disables the specific feature, for
  compatibility with GCC target attributes.
- "<feature>", "no-<feature>" enabled/disables the specific feature, for
  backward compatibility with previous releases.

To do this, the parsing of target attributes has been moved into
TargetInfo to give the target the opportunity to override the existing
parsing. The only non-aarch64 change should be a minor alteration to the
error message, specifying using "CPU" to describe the cpu, not
"architecture", and the DuplicateArch/Tune from ParsedTargetAttr have
been combined into a single option.

Differential Revision: https://reviews.llvm.org/D133848
This commit is contained in:
David Green
2022-10-01 15:40:59 +01:00
parent 4a549be9c3
commit 781b491bba
16 changed files with 363 additions and 121 deletions

View File

@@ -1333,21 +1333,21 @@ static void AppendTargetMangling(const CodeGenModule &CGM,
Out << '.';
const TargetInfo &Target = CGM.getTarget();
ParsedTargetAttr Info =
Attr->parse([&Target](StringRef LHS, StringRef RHS) {
// Multiversioning doesn't allow "no-${feature}", so we can
// only have "+" prefixes here.
assert(LHS.startswith("+") && RHS.startswith("+") &&
"Features should always have a prefix.");
return Target.multiVersionSortPriority(LHS.substr(1)) >
Target.multiVersionSortPriority(RHS.substr(1));
});
ParsedTargetAttr Info = Target.parseTargetAttr(Attr->getFeaturesStr());
llvm::sort(Info.Features, [&Target](StringRef LHS, StringRef RHS) {
// Multiversioning doesn't allow "no-${feature}", so we can
// only have "+" prefixes here.
assert(LHS.startswith("+") && RHS.startswith("+") &&
"Features should always have a prefix.");
return Target.multiVersionSortPriority(LHS.substr(1)) >
Target.multiVersionSortPriority(RHS.substr(1));
});
bool IsFirst = true;
if (!Info.Architecture.empty()) {
if (!Info.CPU.empty()) {
IsFirst = false;
Out << "arch_" << Info.Architecture;
Out << "arch_" << Info.CPU;
}
for (StringRef Feat : Info.Features) {
@@ -2171,10 +2171,11 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
// get and parse the target attribute so we can get the cpu for
// the function.
if (TD) {
ParsedTargetAttr ParsedAttr = TD->parse();
if (!ParsedAttr.Architecture.empty() &&
getTarget().isValidCPUName(ParsedAttr.Architecture)) {
TargetCPU = ParsedAttr.Architecture;
ParsedTargetAttr ParsedAttr =
Target.parseTargetAttr(TD->getFeaturesStr());
if (!ParsedAttr.CPU.empty() &&
getTarget().isValidCPUName(ParsedAttr.CPU)) {
TargetCPU = ParsedAttr.CPU;
TuneCPU = ""; // Clear the tune CPU.
}
if (!ParsedAttr.Tune.empty() &&