@@ -1064,57 +1064,17 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
10641064 return true ;
10651065}
10661066
1067- bool AArch64TargetInfo::initFeatureMap (
1068- llvm::StringMap<bool > &Features, DiagnosticsEngine &Diags, StringRef CPU,
1069- const std::vector<std::string> &FeaturesVec) const {
1070- std::vector<std::string> UpdatedFeaturesVec;
1071- // Parse the CPU and add any implied features.
1072- std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu (CPU);
1073- if (CpuInfo) {
1074- auto Exts = CpuInfo->getImpliedExtensions ();
1075- std::vector<StringRef> CPUFeats;
1076- llvm::AArch64::getExtensionFeatures (Exts, CPUFeats);
1077- for (auto F : CPUFeats) {
1078- assert ((F[0 ] == ' +' || F[0 ] == ' -' ) && " Expected +/- in target feature!" );
1079- UpdatedFeaturesVec.push_back (F.str ());
1080- }
1081- }
1082-
1083- // Process target and dependent features. This is done in two loops collecting
1084- // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
1085- // add target '+/-'features that can later disable some of features added on
1086- // the first loop. Function Multi Versioning features begin with '?'.
1087- for (const auto &Feature : FeaturesVec)
1088- if (((Feature[0 ] == ' ?' || Feature[0 ] == ' +' )) &&
1089- AArch64TargetInfo::doesFeatureAffectCodeGen (Feature.substr (1 ))) {
1090- StringRef DepFeatures =
1091- AArch64TargetInfo::getFeatureDependencies (Feature.substr (1 ));
1092- SmallVector<StringRef, 1 > AttrFeatures;
1093- DepFeatures.split (AttrFeatures, " ," );
1094- for (auto F : AttrFeatures)
1095- UpdatedFeaturesVec.push_back (F.str ());
1096- }
1097- for (const auto &Feature : FeaturesVec)
1098- if (Feature[0 ] != ' ?' ) {
1099- std::string UpdatedFeature = Feature;
1100- if (Feature[0 ] == ' +' ) {
1101- std::optional<llvm::AArch64::ExtensionInfo> Extension =
1102- llvm::AArch64::parseArchExtension (Feature.substr (1 ));
1103- if (Extension)
1104- UpdatedFeature = Extension->Feature .str ();
1105- }
1106- UpdatedFeaturesVec.push_back (UpdatedFeature);
1107- }
1108-
1109- return TargetInfo::initFeatureMap (Features, Diags, CPU, UpdatedFeaturesVec);
1110- }
1111-
11121067// Parse AArch64 Target attributes, which are a comma separated list of:
11131068// "arch=<arch>" - parsed to features as per -march=..
11141069// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
11151070// "tune=<cpu>" - TuneCPU set to <cpu>
11161071// "feature", "no-feature" - Add (or remove) feature.
11171072// "+feature", "+nofeature" - Add (or remove) feature.
1073+ //
1074+ // A feature may correspond to an Extension (anything with a corresponding
1075+ // AEK_), in which case an ExtensionSet is used to parse it and expand its
1076+ // dependencies. If the feature does not yield a successful parse then it
1077+ // is passed through.
11181078ParsedTargetAttr AArch64TargetInfo::parseTargetAttr (StringRef Features) const {
11191079 ParsedTargetAttr Ret;
11201080 if (Features == " default" )
@@ -1124,23 +1084,31 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11241084 bool FoundArch = false ;
11251085
11261086 auto SplitAndAddFeatures = [](StringRef FeatString,
1127- std::vector<std::string> &Features) {
1087+ std::vector<std::string> &Features,
1088+ llvm::AArch64::ExtensionSet &FeatureBits) {
11281089 SmallVector<StringRef, 8 > SplitFeatures;
11291090 FeatString.split (SplitFeatures, StringRef (" +" ), -1 , false );
11301091 for (StringRef Feature : SplitFeatures) {
1131- StringRef FeatureName = llvm::AArch64::getArchExtFeature (Feature);
1132- if (!FeatureName.empty ())
1133- Features.push_back (FeatureName.str ());
1092+ if (FeatureBits.parseModifier (Feature))
1093+ continue ;
1094+ // Pass through anything that failed to parse so that we can emit
1095+ // diagnostics, as well as valid internal feature names.
1096+ //
1097+ // FIXME: We should consider rejecting internal feature names like
1098+ // neon, v8a, etc.
1099+ // FIXME: We should consider emitting diagnostics here.
1100+ if (Feature.starts_with (" no" ))
1101+ Features.push_back (" -" + Feature.drop_front (2 ).str ());
11341102 else
1135- // Pushing the original feature string to give a sema error later on
1136- // when they get checked.
1137- if (Feature.starts_with (" no" ))
1138- Features.push_back (" -" + Feature.drop_front (2 ).str ());
1139- else
1140- Features.push_back (" +" + Feature.str ());
1103+ Features.push_back (" +" + Feature.str ());
11411104 }
11421105 };
11431106
1107+ llvm::AArch64::ExtensionSet FeatureBits;
1108+ // Reconstruct the bitset from the command line option features.
1109+ FeatureBits.reconstructFromParsedFeatures (getTargetOpts ().FeaturesAsWritten ,
1110+ Ret.Features );
1111+
11441112 for (auto &Feature : AttrFeatures) {
11451113 Feature = Feature.trim ();
11461114 if (Feature.starts_with (" fpmath=" ))
@@ -1163,9 +1131,9 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11631131 // Ret.Features.
11641132 if (!AI)
11651133 continue ;
1166- Ret. Features . push_back (AI-> ArchFeature . str () );
1134+ FeatureBits. addArchDefaults (*AI );
11671135 // Add any extra features, after the +
1168- SplitAndAddFeatures (Split.second , Ret.Features );
1136+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits );
11691137 } else if (Feature.starts_with (" cpu=" )) {
11701138 if (!Ret.CPU .empty ())
11711139 Ret.Duplicate = " cpu=" ;
@@ -1175,33 +1143,34 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11751143 std::pair<StringRef, StringRef> Split =
11761144 Feature.split (" =" ).second .trim ().split (" +" );
11771145 Ret.CPU = Split.first ;
1178- SplitAndAddFeatures (Split.second , Ret.Features );
1146+ if (auto CpuInfo = llvm::AArch64::parseCpu (Ret.CPU )) {
1147+ FeatureBits.addCPUDefaults (*CpuInfo);
1148+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits);
1149+ }
11791150 }
11801151 } else if (Feature.starts_with (" tune=" )) {
11811152 if (!Ret.Tune .empty ())
11821153 Ret.Duplicate = " tune=" ;
11831154 else
11841155 Ret.Tune = Feature.split (" =" ).second .trim ();
11851156 } else if (Feature.starts_with (" +" )) {
1186- SplitAndAddFeatures (Feature, Ret.Features );
1187- } else if (Feature.starts_with (" no-" )) {
1188- StringRef FeatureName =
1189- llvm::AArch64::getArchExtFeature (Feature.split (" -" ).second );
1190- if (!FeatureName.empty ())
1191- Ret.Features .push_back (" -" + FeatureName.drop_front (1 ).str ());
1192- else
1193- Ret.Features .push_back (" -" + Feature.split (" -" ).second .str ());
1157+ SplitAndAddFeatures (Feature, Ret.Features , FeatureBits);
11941158 } else {
1195- // Try parsing the string to the internal target feature name. If it is
1196- // invalid, add the original string (which could already be an internal
1197- // name). These should be checked later by isValidFeatureName.
1198- StringRef FeatureName = llvm::AArch64::getArchExtFeature (Feature);
1199- if (!FeatureName.empty ())
1200- Ret.Features .push_back (FeatureName.str ());
1159+ if (FeatureBits.parseModifier (Feature, /* AllowNoDashForm = */ true ))
1160+ continue ;
1161+ // Pass through anything that failed to parse so that we can emit
1162+ // diagnostics, as well as valid internal feature names.
1163+ //
1164+ // FIXME: We should consider rejecting internal feature names like
1165+ // neon, v8a, etc.
1166+ // FIXME: We should consider emitting diagnostics here.
1167+ if (Feature.starts_with (" no-" ))
1168+ Ret.Features .push_back (" -" + Feature.drop_front (3 ).str ());
12011169 else
12021170 Ret.Features .push_back (" +" + Feature.str ());
12031171 }
12041172 }
1173+ FeatureBits.toLLVMFeatureList (Ret.Features );
12051174 return Ret;
12061175}
12071176
0 commit comments