Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions llvm/include/llvm/TargetParser/SubtargetFeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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.
Expand Down
35 changes: 26 additions & 9 deletions llvm/lib/MC/MCSubtargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down