From 28ca7f52bff3572a454a296283a88a80ee2ccbda Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 12 Mar 2025 10:36:41 +0100 Subject: [PATCH 1/2] [MC] Speed up checkFeatures() (NFCI) checkFeatures() currently goes through ApplyFeatureFlag(), which will also handle implied features. This is very slow -- just querying every feature once takes up 10% of a Rust hello world compile. However, if we only want to query whether certain features are set/unset, we can do so directly -- implied features have already been handled when the FeatureBitset was constructed. I've retained the existing handling for unrecognized features (print an error and ignore them). --- llvm/lib/MC/MCSubtargetInfo.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp index f59ec2f7c2602..815e092deef22 100644 --- a/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/llvm/lib/MC/MCSubtargetInfo.cpp @@ -317,14 +317,20 @@ FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { bool MCSubtargetInfo::checkFeatures(StringRef FS) const { SubtargetFeatures T(FS); - FeatureBitset Set, All; - for (std::string F : T.getFeatures()) { - ::ApplyFeatureFlag(Set, F, ProcFeatures); - if (F[0] == '-') - F[0] = '+'; - ::ApplyFeatureFlag(All, F, ProcFeatures); - } - return (FeatureBits & All) == Set; + return all_of(T.getFeatures(), [this](const std::string &F) { + assert(SubtargetFeatures::hasFlag(F) && + "Feature flags should start with '+' or '-'"); + const SubtargetFeatureKV *FeatureEntry = + Find(SubtargetFeatures::StripFlag(F), ProcFeatures); + if (!FeatureEntry) { + errs() << "'" << F << "' is not a recognized feature for this target" + << " (ignoring feature)\n"; + return true; + } + + return FeatureBits.test(FeatureEntry->Value) == + SubtargetFeatures::isEnabled(F); + }); } const MCSchedModel &MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { From 22fa3c85265d2e0e3c7fddbe79b4ca6e5c35e263 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 12 Mar 2025 11:54:47 +0100 Subject: [PATCH 2/2] Use report_fatal_error instead --- llvm/lib/MC/MCSubtargetInfo.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp index 815e092deef22..d86eaad48420d 100644 --- a/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/llvm/lib/MC/MCSubtargetInfo.cpp @@ -322,11 +322,9 @@ bool MCSubtargetInfo::checkFeatures(StringRef FS) const { "Feature flags should start with '+' or '-'"); const SubtargetFeatureKV *FeatureEntry = Find(SubtargetFeatures::StripFlag(F), ProcFeatures); - if (!FeatureEntry) { - errs() << "'" << F << "' is not a recognized feature for this target" - << " (ignoring feature)\n"; - return true; - } + if (!FeatureEntry) + report_fatal_error(Twine("'") + F + + "' is not a recognized feature for this target"); return FeatureBits.test(FeatureEntry->Value) == SubtargetFeatures::isEnabled(F);