@@ -1050,57 +1050,18 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
1050
1050
return true ;
1051
1051
}
1052
1052
1053
- bool AArch64TargetInfo::initFeatureMap (
1054
- llvm::StringMap<bool > &Features, DiagnosticsEngine &Diags, StringRef CPU,
1055
- const std::vector<std::string> &FeaturesVec) const {
1056
- std::vector<std::string> UpdatedFeaturesVec;
1057
- // Parse the CPU and add any implied features.
1058
- std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu (CPU);
1059
- if (CpuInfo) {
1060
- auto Exts = CpuInfo->getImpliedExtensions ();
1061
- std::vector<StringRef> CPUFeats;
1062
- llvm::AArch64::getExtensionFeatures (Exts, CPUFeats);
1063
- for (auto F : CPUFeats) {
1064
- assert ((F[0 ] == ' +' || F[0 ] == ' -' ) && " Expected +/- in target feature!" );
1065
- UpdatedFeaturesVec.push_back (F.str ());
1066
- }
1067
- }
1068
-
1069
- // Process target and dependent features. This is done in two loops collecting
1070
- // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
1071
- // add target '+/-'features that can later disable some of features added on
1072
- // the first loop. Function Multi Versioning features begin with '?'.
1073
- for (const auto &Feature : FeaturesVec)
1074
- if (((Feature[0 ] == ' ?' || Feature[0 ] == ' +' )) &&
1075
- AArch64TargetInfo::doesFeatureAffectCodeGen (Feature.substr (1 ))) {
1076
- StringRef DepFeatures =
1077
- AArch64TargetInfo::getFeatureDependencies (Feature.substr (1 ));
1078
- SmallVector<StringRef, 1 > AttrFeatures;
1079
- DepFeatures.split (AttrFeatures, " ," );
1080
- for (auto F : AttrFeatures)
1081
- UpdatedFeaturesVec.push_back (F.str ());
1082
- }
1083
- for (const auto &Feature : FeaturesVec)
1084
- if (Feature[0 ] != ' ?' ) {
1085
- std::string UpdatedFeature = Feature;
1086
- if (Feature[0 ] == ' +' ) {
1087
- std::optional<llvm::AArch64::ExtensionInfo> Extension =
1088
- llvm::AArch64::parseArchExtension (Feature.substr (1 ));
1089
- if (Extension)
1090
- UpdatedFeature = Extension->Feature .str ();
1091
- }
1092
- UpdatedFeaturesVec.push_back (UpdatedFeature);
1093
- }
1094
-
1095
- return TargetInfo::initFeatureMap (Features, Diags, CPU, UpdatedFeaturesVec);
1096
- }
1097
-
1098
1053
// Parse AArch64 Target attributes, which are a comma separated list of:
1099
1054
// "arch=<arch>" - parsed to features as per -march=..
1100
1055
// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1101
1056
// "tune=<cpu>" - TuneCPU set to <cpu>
1102
1057
// "feature", "no-feature" - Add (or remove) feature.
1103
1058
// "+feature", "+nofeature" - Add (or remove) feature.
1059
+ //
1060
+ // A feature may correspond to an Extension (anything with a corresponding
1061
+ // AEK_), in which case an ExtensionSet is used to parse it and expand its
1062
+ // dependencies. Otherwise the feature is passed through (e.g. +v8.1a,
1063
+ // +outline-atomics, -fmv, etc). Features coming from the command line are
1064
+ // already parsed, therefore their dependencies do not need expansion.
1104
1065
ParsedTargetAttr AArch64TargetInfo::parseTargetAttr (StringRef Features) const {
1105
1066
ParsedTargetAttr Ret;
1106
1067
if (Features == " default" )
@@ -1110,23 +1071,26 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1110
1071
bool FoundArch = false ;
1111
1072
1112
1073
auto SplitAndAddFeatures = [](StringRef FeatString,
1113
- std::vector<std::string> &Features) {
1074
+ std::vector<std::string> &Features,
1075
+ llvm::AArch64::ExtensionSet &FeatureBits) {
1114
1076
SmallVector<StringRef, 8 > SplitFeatures;
1115
1077
FeatString.split (SplitFeatures, StringRef (" +" ), -1 , false );
1116
1078
for (StringRef Feature : SplitFeatures) {
1117
- StringRef FeatureName = llvm::AArch64::getArchExtFeature (Feature);
1118
- if (!FeatureName.empty ())
1119
- Features.push_back (FeatureName.str ());
1079
+ if (FeatureBits.parseModifier (Feature, /* AllowNoDashForm = */ true ))
1080
+ continue ;
1081
+ // Pass through features that are not extensions, e.g. +v8.1a,
1082
+ // +outline-atomics, -fmv, etc.
1083
+ if (Feature.starts_with (" no" ))
1084
+ Features.push_back (" -" + Feature.drop_front (2 ).str ());
1120
1085
else
1121
- // Pushing the original feature string to give a sema error later on
1122
- // when they get checked.
1123
- if (Feature.starts_with (" no" ))
1124
- Features.push_back (" -" + Feature.drop_front (2 ).str ());
1125
- else
1126
- Features.push_back (" +" + Feature.str ());
1086
+ Features.push_back (" +" + Feature.str ());
1127
1087
}
1128
1088
};
1129
1089
1090
+ llvm::AArch64::ExtensionSet FeatureBits;
1091
+ // Reconstruct the bitset from the command line option features.
1092
+ FeatureBits.reconstructFromParsedFeatures (getTargetOpts ().FeaturesAsWritten );
1093
+
1130
1094
for (auto &Feature : AttrFeatures) {
1131
1095
Feature = Feature.trim ();
1132
1096
if (Feature.starts_with (" fpmath=" ))
@@ -1149,9 +1113,9 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1149
1113
// Ret.Features.
1150
1114
if (!AI)
1151
1115
continue ;
1152
- Ret. Features . push_back (AI-> ArchFeature . str () );
1116
+ FeatureBits. addArchDefaults (*AI );
1153
1117
// Add any extra features, after the +
1154
- SplitAndAddFeatures (Split.second , Ret.Features );
1118
+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits );
1155
1119
} else if (Feature.starts_with (" cpu=" )) {
1156
1120
if (!Ret.CPU .empty ())
1157
1121
Ret.Duplicate = " cpu=" ;
@@ -1161,33 +1125,30 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1161
1125
std::pair<StringRef, StringRef> Split =
1162
1126
Feature.split (" =" ).second .trim ().split (" +" );
1163
1127
Ret.CPU = Split.first ;
1164
- SplitAndAddFeatures (Split.second , Ret.Features );
1128
+ if (auto CpuInfo = llvm::AArch64::parseCpu (Ret.CPU )) {
1129
+ FeatureBits.addCPUDefaults (*CpuInfo);
1130
+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits);
1131
+ }
1165
1132
}
1166
1133
} else if (Feature.starts_with (" tune=" )) {
1167
1134
if (!Ret.Tune .empty ())
1168
1135
Ret.Duplicate = " tune=" ;
1169
1136
else
1170
1137
Ret.Tune = Feature.split (" =" ).second .trim ();
1171
1138
} else if (Feature.starts_with (" +" )) {
1172
- SplitAndAddFeatures (Feature, Ret.Features );
1173
- } else if (Feature.starts_with (" no-" )) {
1174
- StringRef FeatureName =
1175
- llvm::AArch64::getArchExtFeature (Feature.split (" -" ).second );
1176
- if (!FeatureName.empty ())
1177
- Ret.Features .push_back (" -" + FeatureName.drop_front (1 ).str ());
1178
- else
1179
- Ret.Features .push_back (" -" + Feature.split (" -" ).second .str ());
1139
+ SplitAndAddFeatures (Feature, Ret.Features , FeatureBits);
1180
1140
} else {
1181
- // Try parsing the string to the internal target feature name. If it is
1182
- // invalid, add the original string (which could already be an internal
1183
- // name). These should be checked later by isValidFeatureName.
1184
- StringRef FeatureName = llvm::AArch64::getArchExtFeature (Feature);
1185
- if (!FeatureName. empty ( ))
1186
- Ret.Features .push_back (FeatureName .str ());
1141
+ if (FeatureBits. parseModifier (Feature, /* AllowNoDashForm = */ true ))
1142
+ continue ;
1143
+ // Pass through features that are not extensions, e.g. +v8.1a,
1144
+ // +outline-atomics, -fmv, etc.
1145
+ if (Feature. starts_with ( " no- " ))
1146
+ Ret.Features .push_back (" - " + Feature. drop_front ( 3 ) .str ());
1187
1147
else
1188
1148
Ret.Features .push_back (" +" + Feature.str ());
1189
1149
}
1190
1150
}
1151
+ FeatureBits.toLLVMFeatureList (Ret.Features );
1191
1152
return Ret;
1192
1153
}
1193
1154
0 commit comments