[llvm] [MC][TargetParser] Optimize SetImpliedBits. (PR #164583)
Weng Jinrui via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 22 02:08:41 PDT 2025
https://github.com/wjr-z created https://github.com/llvm/llvm-project/pull/164583
Optimize SetImpliedBits, avoid repeated updates multiple times
>From 316b7e23fbd1ffcaa30dc98319aeafc16856f452 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=81=E9=94=A6=E7=91=9E?= <jrweng at rgf006.bw.local>
Date: Wed, 22 Oct 2025 16:48:02 +0800
Subject: [PATCH] [MC][TargetParser] Optimize SetImpliedBits.
---
.../llvm/TargetParser/SubtargetFeature.h | 13 +++++++
llvm/lib/MC/MCSubtargetInfo.cpp | 35 ++++++++++++++-----
2 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/SubtargetFeature.h b/llvm/include/llvm/TargetParser/SubtargetFeature.h
index a48b18745352a..a5bf1ef72fa68 100644
--- a/llvm/include/llvm/TargetParser/SubtargetFeature.h
+++ b/llvm/include/llvm/TargetParser/SubtargetFeature.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/bit.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include <array>
@@ -151,6 +152,18 @@ class FeatureBitset {
}
return false;
}
+
+ template <typename Func>
+ constexpr void forEachBit(Func func) const {
+ for (unsigned I = 0; I < MAX_SUBTARGET_WORDS; ++I) {
+ uint64_t Word = Bits[I];
+ while (Word) {
+ unsigned Bit = llvm::countr_zero(Word);
+ Word &= Word - 1;
+ func(I * 64 + Bit);
+ }
+ }
+ }
};
/// Class used to store the subtarget bits in the tables created by tablegen.
diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp
index 89a08327dd259..77ea1bc5aa040 100644
--- a/llvm/lib/MC/MCSubtargetInfo.cpp
+++ b/llvm/lib/MC/MCSubtargetInfo.cpp
@@ -34,15 +34,32 @@ static const T *Find(StringRef S, ArrayRef<T> A) {
}
/// For each feature that is (transitively) implied by this feature, set it.
-static
-void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies,
- ArrayRef<SubtargetFeatureKV> FeatureTable) {
- // OR the Implies bits in outside the loop. This allows the Implies for CPUs
- // which might imply features not in FeatureTable to use this.
- Bits |= Implies;
- for (const SubtargetFeatureKV &FE : FeatureTable)
- if (Implies.test(FE.Value))
- SetImpliedBits(Bits, FE.Implies.getAsBitset(), FeatureTable);
+static void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies,
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+ std::array<uint16_t, MAX_SUBTARGET_FEATURES> featureMap;
+ FeatureBitset Mask;
+ uint16_t idx = 0;
+ for (const auto &FE : FeatureTable) {
+ Mask.set(FE.Value);
+ featureMap[FE.Value] = idx++;
+ }
+
+ FeatureBitset impl(Implies);
+ while (true) {
+ Bits |= impl;
+ auto newImplies = Mask & impl;
+ if (newImplies.none()) {
+ break;
+ }
+
+ Mask ^= newImplies;
+ impl = FeatureBitset();
+
+ newImplies.forEachBit([&](unsigned Bit) {
+ unsigned idx = featureMap[Bit];
+ impl |= FeatureTable[idx].Implies.getAsBitset();
+ });
+ }
}
/// For each feature that (transitively) implies this feature, clear it.
More information about the llvm-commits
mailing list