@@ -1052,57 +1052,18 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
10521052 return true ;
10531053}
10541054
1055- bool AArch64TargetInfo::initFeatureMap (
1056- llvm::StringMap<bool > &Features, DiagnosticsEngine &Diags, StringRef CPU,
1057- const std::vector<std::string> &FeaturesVec) const {
1058- std::vector<std::string> UpdatedFeaturesVec;
1059- // Parse the CPU and add any implied features.
1060- std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu (CPU);
1061- if (CpuInfo) {
1062- auto Exts = CpuInfo->getImpliedExtensions ();
1063- std::vector<StringRef> CPUFeats;
1064- llvm::AArch64::getExtensionFeatures (Exts, CPUFeats);
1065- for (auto F : CPUFeats) {
1066- assert ((F[0 ] == ' +' || F[0 ] == ' -' ) && " Expected +/- in target feature!" );
1067- UpdatedFeaturesVec.push_back (F.str ());
1068- }
1069- }
1070-
1071- // Process target and dependent features. This is done in two loops collecting
1072- // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
1073- // add target '+/-'features that can later disable some of features added on
1074- // the first loop. Function Multi Versioning features begin with '?'.
1075- for (const auto &Feature : FeaturesVec)
1076- if (((Feature[0 ] == ' ?' || Feature[0 ] == ' +' )) &&
1077- AArch64TargetInfo::doesFeatureAffectCodeGen (Feature.substr (1 ))) {
1078- StringRef DepFeatures =
1079- AArch64TargetInfo::getFeatureDependencies (Feature.substr (1 ));
1080- SmallVector<StringRef, 1 > AttrFeatures;
1081- DepFeatures.split (AttrFeatures, " ," );
1082- for (auto F : AttrFeatures)
1083- UpdatedFeaturesVec.push_back (F.str ());
1084- }
1085- for (const auto &Feature : FeaturesVec)
1086- if (Feature[0 ] != ' ?' ) {
1087- std::string UpdatedFeature = Feature;
1088- if (Feature[0 ] == ' +' ) {
1089- std::optional<llvm::AArch64::ExtensionInfo> Extension =
1090- llvm::AArch64::parseArchExtension (Feature.substr (1 ));
1091- if (Extension)
1092- UpdatedFeature = Extension->Feature .str ();
1093- }
1094- UpdatedFeaturesVec.push_back (UpdatedFeature);
1095- }
1096-
1097- return TargetInfo::initFeatureMap (Features, Diags, CPU, UpdatedFeaturesVec);
1098- }
1099-
11001055// Parse AArch64 Target attributes, which are a comma separated list of:
11011056// "arch=<arch>" - parsed to features as per -march=..
11021057// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
11031058// "tune=<cpu>" - TuneCPU set to <cpu>
11041059// "feature", "no-feature" - Add (or remove) feature.
11051060// "+feature", "+nofeature" - Add (or remove) feature.
1061+ //
1062+ // A feature may correspond to an Extension (anything with a corresponding
1063+ // AEK_), in which case an ExtensionSet is used to parse it and expand its
1064+ // dependencies. Otherwise the feature is passed through (e.g. +v8.1a,
1065+ // +outline-atomics, -fmv, etc). Features coming from the command line are
1066+ // already parsed, therefore their dependencies do not need expansion.
11061067ParsedTargetAttr AArch64TargetInfo::parseTargetAttr (StringRef Features) const {
11071068 ParsedTargetAttr Ret;
11081069 if (Features == " default" )
@@ -1112,23 +1073,26 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11121073 bool FoundArch = false ;
11131074
11141075 auto SplitAndAddFeatures = [](StringRef FeatString,
1115- std::vector<std::string> &Features) {
1076+ std::vector<std::string> &Features,
1077+ llvm::AArch64::ExtensionSet &FeatureBits) {
11161078 SmallVector<StringRef, 8 > SplitFeatures;
11171079 FeatString.split (SplitFeatures, StringRef (" +" ), -1 , false );
11181080 for (StringRef Feature : SplitFeatures) {
1119- StringRef FeatureName = llvm::AArch64::getArchExtFeature (Feature);
1120- if (!FeatureName.empty ())
1121- Features.push_back (FeatureName.str ());
1081+ if (FeatureBits.parseModifier (Feature, /* AllowNoDashForm = */ true ))
1082+ continue ;
1083+ // Pass through features that are not extensions, e.g. +v8.1a,
1084+ // +outline-atomics, -fmv, etc.
1085+ if (Feature.starts_with (" no" ))
1086+ Features.push_back (" -" + Feature.drop_front (2 ).str ());
11221087 else
1123- // Pushing the original feature string to give a sema error later on
1124- // when they get checked.
1125- if (Feature.starts_with (" no" ))
1126- Features.push_back (" -" + Feature.drop_front (2 ).str ());
1127- else
1128- Features.push_back (" +" + Feature.str ());
1088+ Features.push_back (" +" + Feature.str ());
11291089 }
11301090 };
11311091
1092+ llvm::AArch64::ExtensionSet FeatureBits;
1093+ // Reconstruct the bitset from the command line option features.
1094+ FeatureBits.reconstructFromParsedFeatures (getTargetOpts ().FeaturesAsWritten );
1095+
11321096 for (auto &Feature : AttrFeatures) {
11331097 Feature = Feature.trim ();
11341098 if (Feature.starts_with (" fpmath=" ))
@@ -1151,9 +1115,9 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11511115 // Ret.Features.
11521116 if (!AI)
11531117 continue ;
1154- Ret. Features . push_back (AI-> ArchFeature . str () );
1118+ FeatureBits. addArchDefaults (*AI );
11551119 // Add any extra features, after the +
1156- SplitAndAddFeatures (Split.second , Ret.Features );
1120+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits );
11571121 } else if (Feature.starts_with (" cpu=" )) {
11581122 if (!Ret.CPU .empty ())
11591123 Ret.Duplicate = " cpu=" ;
@@ -1163,33 +1127,30 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11631127 std::pair<StringRef, StringRef> Split =
11641128 Feature.split (" =" ).second .trim ().split (" +" );
11651129 Ret.CPU = Split.first ;
1166- SplitAndAddFeatures (Split.second , Ret.Features );
1130+ if (auto CpuInfo = llvm::AArch64::parseCpu (Ret.CPU )) {
1131+ FeatureBits.addCPUDefaults (*CpuInfo);
1132+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits);
1133+ }
11671134 }
11681135 } else if (Feature.starts_with (" tune=" )) {
11691136 if (!Ret.Tune .empty ())
11701137 Ret.Duplicate = " tune=" ;
11711138 else
11721139 Ret.Tune = Feature.split (" =" ).second .trim ();
11731140 } else if (Feature.starts_with (" +" )) {
1174- SplitAndAddFeatures (Feature, Ret.Features );
1175- } else if (Feature.starts_with (" no-" )) {
1176- StringRef FeatureName =
1177- llvm::AArch64::getArchExtFeature (Feature.split (" -" ).second );
1178- if (!FeatureName.empty ())
1179- Ret.Features .push_back (" -" + FeatureName.drop_front (1 ).str ());
1180- else
1181- Ret.Features .push_back (" -" + Feature.split (" -" ).second .str ());
1141+ SplitAndAddFeatures (Feature, Ret.Features , FeatureBits);
11821142 } else {
1183- // Try parsing the string to the internal target feature name. If it is
1184- // invalid, add the original string (which could already be an internal
1185- // name). These should be checked later by isValidFeatureName.
1186- StringRef FeatureName = llvm::AArch64::getArchExtFeature (Feature);
1187- if (!FeatureName. empty ( ))
1188- Ret.Features .push_back (FeatureName .str ());
1143+ if (FeatureBits. parseModifier (Feature, /* AllowNoDashForm = */ true ))
1144+ continue ;
1145+ // Pass through features that are not extensions, e.g. +v8.1a,
1146+ // +outline-atomics, -fmv, etc.
1147+ if (Feature. starts_with ( " no- " ))
1148+ Ret.Features .push_back (" - " + Feature. drop_front ( 3 ) .str ());
11891149 else
11901150 Ret.Features .push_back (" +" + Feature.str ());
11911151 }
11921152 }
1153+ FeatureBits.toLLVMFeatureList (Ret.Features );
11931154 return Ret;
11941155}
11951156
0 commit comments