@@ -1052,57 +1052,18 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
1052
1052
return true ;
1053
1053
}
1054
1054
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
-
1100
1055
// Parse AArch64 Target attributes, which are a comma separated list of:
1101
1056
// "arch=<arch>" - parsed to features as per -march=..
1102
1057
// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1103
1058
// "tune=<cpu>" - TuneCPU set to <cpu>
1104
1059
// "feature", "no-feature" - Add (or remove) feature.
1105
1060
// "+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.
1106
1067
ParsedTargetAttr AArch64TargetInfo::parseTargetAttr (StringRef Features) const {
1107
1068
ParsedTargetAttr Ret;
1108
1069
if (Features == " default" )
@@ -1112,23 +1073,26 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1112
1073
bool FoundArch = false ;
1113
1074
1114
1075
auto SplitAndAddFeatures = [](StringRef FeatString,
1115
- std::vector<std::string> &Features) {
1076
+ std::vector<std::string> &Features,
1077
+ llvm::AArch64::ExtensionSet &FeatureBits) {
1116
1078
SmallVector<StringRef, 8 > SplitFeatures;
1117
1079
FeatString.split (SplitFeatures, StringRef (" +" ), -1 , false );
1118
1080
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 ());
1122
1087
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 ());
1129
1089
}
1130
1090
};
1131
1091
1092
+ llvm::AArch64::ExtensionSet FeatureBits;
1093
+ // Reconstruct the bitset from the command line option features.
1094
+ FeatureBits.reconstructFromParsedFeatures (getTargetOpts ().FeaturesAsWritten );
1095
+
1132
1096
for (auto &Feature : AttrFeatures) {
1133
1097
Feature = Feature.trim ();
1134
1098
if (Feature.starts_with (" fpmath=" ))
@@ -1151,9 +1115,9 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1151
1115
// Ret.Features.
1152
1116
if (!AI)
1153
1117
continue ;
1154
- Ret. Features . push_back (AI-> ArchFeature . str () );
1118
+ FeatureBits. addArchDefaults (*AI );
1155
1119
// Add any extra features, after the +
1156
- SplitAndAddFeatures (Split.second , Ret.Features );
1120
+ SplitAndAddFeatures (Split.second , Ret.Features , FeatureBits );
1157
1121
} else if (Feature.starts_with (" cpu=" )) {
1158
1122
if (!Ret.CPU .empty ())
1159
1123
Ret.Duplicate = " cpu=" ;
@@ -1163,33 +1127,30 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1163
1127
std::pair<StringRef, StringRef> Split =
1164
1128
Feature.split (" =" ).second .trim ().split (" +" );
1165
1129
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
+ }
1167
1134
}
1168
1135
} else if (Feature.starts_with (" tune=" )) {
1169
1136
if (!Ret.Tune .empty ())
1170
1137
Ret.Duplicate = " tune=" ;
1171
1138
else
1172
1139
Ret.Tune = Feature.split (" =" ).second .trim ();
1173
1140
} 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);
1182
1142
} 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 ());
1189
1149
else
1190
1150
Ret.Features .push_back (" +" + Feature.str ());
1191
1151
}
1192
1152
}
1153
+ FeatureBits.toLLVMFeatureList (Ret.Features );
1193
1154
return Ret;
1194
1155
}
1195
1156
0 commit comments