@@ -235,6 +235,47 @@ ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
235
235
clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
236
236
}
237
237
238
+ static std::vector<std::string>
239
+ collectNonISAExtFeature (const std::vector<std::string> &FeaturesNeedOverride,
240
+ int XLen) {
241
+ auto ParseResult =
242
+ llvm::RISCVISAInfo::parseFeatures (XLen, FeaturesNeedOverride);
243
+
244
+ if (!ParseResult) {
245
+ consumeError (ParseResult.takeError ());
246
+ return std::vector<std::string>();
247
+ }
248
+
249
+ std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector ();
250
+
251
+ std::vector<std::string> NonISAExtFeatureVec;
252
+
253
+ llvm::copy_if (FeaturesNeedOverride, std::back_inserter (NonISAExtFeatureVec),
254
+ [&](const std::string &Feat) {
255
+ return !llvm::is_contained (ImpliedFeatures, Feat);
256
+ });
257
+
258
+ return NonISAExtFeatureVec;
259
+ }
260
+
261
+ static std::vector<std::string>
262
+ resolveTargetAttrOverride (const std::vector<std::string> &FeaturesVec,
263
+ int XLen) {
264
+ auto I = llvm::find (FeaturesVec, " __RISCV_TargetAttrNeedOverride" );
265
+ if (I == FeaturesVec.end ())
266
+ return FeaturesVec;
267
+
268
+ const std::vector<std::string> FeaturesNeedOverride (FeaturesVec.begin (), I);
269
+ std::vector<std::string> NonISAExtFeature =
270
+ collectNonISAExtFeature (FeaturesNeedOverride, XLen);
271
+
272
+ auto ResolvedFeature = std::vector (++I, FeaturesVec.end ());
273
+ ResolvedFeature.insert (ResolvedFeature.end (), NonISAExtFeature.begin (),
274
+ NonISAExtFeature.end ());
275
+
276
+ return ResolvedFeature;
277
+ }
278
+
238
279
bool RISCVTargetInfo::initFeatureMap (
239
280
llvm::StringMap<bool > &Features, DiagnosticsEngine &Diags, StringRef CPU,
240
281
const std::vector<std::string> &FeaturesVec) const {
@@ -248,7 +289,10 @@ bool RISCVTargetInfo::initFeatureMap(
248
289
Features[" 32bit" ] = true ;
249
290
}
250
291
251
- auto ParseResult = llvm::RISCVISAInfo::parseFeatures (XLen, FeaturesVec);
292
+ std::vector<std::string> NewFeaturesVec =
293
+ resolveTargetAttrOverride (FeaturesVec, XLen);
294
+
295
+ auto ParseResult = llvm::RISCVISAInfo::parseFeatures (XLen, NewFeaturesVec);
252
296
if (!ParseResult) {
253
297
std::string Buffer;
254
298
llvm::raw_string_ostream OutputErrMsg (Buffer);
@@ -262,7 +306,7 @@ bool RISCVTargetInfo::initFeatureMap(
262
306
// RISCVISAInfo makes implications for ISA features
263
307
std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector ();
264
308
// Add non-ISA features like `relax` and `save-restore` back
265
- for (const std::string &Feature : FeaturesVec )
309
+ for (const std::string &Feature : NewFeaturesVec )
266
310
if (!llvm::is_contained (ImpliedFeatures, Feature))
267
311
ImpliedFeatures.push_back (Feature);
268
312
@@ -359,3 +403,82 @@ void RISCVTargetInfo::fillValidTuneCPUList(
359
403
bool Is64Bit = getTriple ().isArch64Bit ();
360
404
llvm::RISCV::fillValidTuneCPUArchList (Values, Is64Bit);
361
405
}
406
+
407
+ static void handleFullArchString (StringRef FullArchStr,
408
+ std::vector<std::string> &Features) {
409
+ Features.push_back (" __RISCV_TargetAttrNeedOverride" );
410
+ auto RII = llvm::RISCVISAInfo::parseArchString (
411
+ FullArchStr, /* EnableExperimentalExtension */ true );
412
+ if (!RII) {
413
+ consumeError (RII.takeError ());
414
+ // Forward the invalid FullArchStr.
415
+ Features.push_back (" +" + FullArchStr.str ());
416
+ } else {
417
+ std::vector<std::string> FeatStrings = (*RII)->toFeatureVector ();
418
+ for (auto FeatString : FeatStrings)
419
+ Features.push_back (FeatString);
420
+ }
421
+ }
422
+
423
+ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr (StringRef Features) const {
424
+ ParsedTargetAttr Ret;
425
+ if (Features == " default" )
426
+ return Ret;
427
+ SmallVector<StringRef, 1 > AttrFeatures;
428
+ Features.split (AttrFeatures, " ;" );
429
+ bool FoundArch = false ;
430
+
431
+ for (auto &Feature : AttrFeatures) {
432
+ Feature = Feature.trim ();
433
+ StringRef AttrString = Feature.split (" =" ).second .trim ();
434
+
435
+ if (Feature.startswith (" arch=" )) {
436
+ // Override last features
437
+ Ret.Features .clear ();
438
+ if (FoundArch)
439
+ Ret.Duplicate = " arch=" ;
440
+ FoundArch = true ;
441
+
442
+ if (AttrString.startswith (" +" )) {
443
+ // EXTENSION like arch=+v,+zbb
444
+ SmallVector<StringRef, 1 > Exts;
445
+ AttrString.split (Exts, " ," );
446
+ for (auto Ext : Exts) {
447
+ if (Ext.empty ())
448
+ continue ;
449
+
450
+ StringRef ExtName = Ext.substr (1 );
451
+ std::string TargetFeature =
452
+ llvm::RISCVISAInfo::getTargetFeatureForExtension (ExtName);
453
+ if (!TargetFeature.empty ())
454
+ Ret.Features .push_back (Ext.front () + TargetFeature);
455
+ else
456
+ Ret.Features .push_back (Ext.str ());
457
+ }
458
+ } else {
459
+ // full-arch-string like arch=rv64gcv
460
+ handleFullArchString (AttrString, Ret.Features );
461
+ }
462
+ } else if (Feature.startswith (" cpu=" )) {
463
+ if (!Ret.CPU .empty ())
464
+ Ret.Duplicate = " cpu=" ;
465
+
466
+ Ret.CPU = AttrString;
467
+
468
+ if (!FoundArch) {
469
+ // Update Features with CPU's features
470
+ StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu (Ret.CPU );
471
+ if (MarchFromCPU != " " ) {
472
+ Ret.Features .clear ();
473
+ handleFullArchString (MarchFromCPU, Ret.Features );
474
+ }
475
+ }
476
+ } else if (Feature.startswith (" tune=" )) {
477
+ if (!Ret.Tune .empty ())
478
+ Ret.Duplicate = " tune=" ;
479
+
480
+ Ret.Tune = AttrString;
481
+ }
482
+ }
483
+ return Ret;
484
+ }
0 commit comments