@@ -250,12 +250,17 @@ bool RISCVTargetInfo::initFeatureMap(
250250
251251 // RISCVISAInfo makes implications for ISA features
252252 std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector ();
253+ std::vector<std::string> UpdatedFeatures;
254+
253255 // Add non-ISA features like `relax` and `save-restore` back
254256 for (const std::string &Feature : FeaturesVec)
255257 if (!llvm::is_contained (ImpliedFeatures, Feature))
256- ImpliedFeatures.push_back (Feature);
258+ UpdatedFeatures.push_back (Feature);
259+
260+ UpdatedFeatures.insert (UpdatedFeatures.end (), ImpliedFeatures.begin (),
261+ ImpliedFeatures.end ());
257262
258- return TargetInfo::initFeatureMap (Features, Diags, CPU, ImpliedFeatures );
263+ return TargetInfo::initFeatureMap (Features, Diags, CPU, UpdatedFeatures );
259264}
260265
261266std::optional<std::pair<unsigned , unsigned >>
@@ -346,3 +351,74 @@ void RISCVTargetInfo::fillValidTuneCPUList(
346351 bool Is64Bit = getTriple ().isArch64Bit ();
347352 llvm::RISCV::fillValidTuneCPUArchList (Values, Is64Bit);
348353}
354+
355+ // Parse RISC-V Target attributes, which are a comma separated list of:
356+ // "arch=<arch>" - parsed to features as per -march=..
357+ // "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
358+ // "tune=<cpu>" - TuneCPU set to <cpu>
359+ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr (StringRef Features) const {
360+ ParsedTargetAttr Ret;
361+ if (Features == " default" )
362+ return Ret;
363+ SmallVector<StringRef, 1 > AttrFeatures;
364+ Features.split (AttrFeatures, " ;" );
365+ bool FoundArch = false ;
366+
367+ for (auto &Feature : AttrFeatures) {
368+ Feature = Feature.trim ();
369+ StringRef AttrString = Feature.split (" =" ).second .trim ();
370+
371+ if (Feature.startswith (" arch=" )) {
372+ if (FoundArch)
373+ Ret.Duplicate = " arch=" ;
374+ FoundArch = true ;
375+
376+ if (AttrString.startswith (" +" )) {
377+ // EXTENSION like arch=+v,+zbb
378+ SmallVector<StringRef, 1 > Exts;
379+ AttrString.split (Exts, " ," );
380+ for (auto Ext : Exts) {
381+ if (Ext.empty ())
382+ continue ;
383+
384+ StringRef ExtName = Ext.substr (1 );
385+ std::string TargetFeature =
386+ llvm::RISCVISAInfo::getTargetFeatureForExtension (ExtName);
387+ if (!TargetFeature.empty ())
388+ Ret.Features .push_back (Ext.front () + TargetFeature);
389+ else
390+ Ret.Features .push_back (Ext.str ());
391+ }
392+ } else {
393+ // full-arch-string like arch=rv64gcv
394+ auto RII = llvm::RISCVISAInfo::parseArchString (
395+ AttrString, /* EnableExperimentalExtension */ true );
396+ if (!RII) {
397+ consumeError (RII.takeError ());
398+ } else {
399+ std::vector<std::string> FeatStrings = (*RII)->toFeatureVector ();
400+ for (auto FeatString : FeatStrings)
401+ Ret.Features .push_back (FeatString);
402+ }
403+ }
404+ continue ;
405+ } else if (Feature.startswith (" cpu=" )) {
406+ if (!Ret.CPU .empty ())
407+ Ret.Duplicate = " cpu=" ;
408+ else
409+ Ret.CPU = AttrString;
410+ continue ;
411+ } else if (Feature.startswith (" tune=" )) {
412+ if (!Ret.Tune .empty ())
413+ Ret.Duplicate = " tune=" ;
414+ else
415+ Ret.Tune = AttrString;
416+ continue ;
417+ }
418+ }
419+ return Ret;
420+ }
421+
422+ bool RISCVTargetInfo::validateCpuSupports (StringRef FeatureStr) const {
423+ return ISAInfo->isSupportedExtensionFeature (FeatureStr);
424+ }
0 commit comments