[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