Skip to content
This repository was archived by the owner on Jan 26, 2024. It is now read-only.

Commit 0c7af8c

Browse files
committed
[X86] Optimize getImpliedDisabledFeatures & getImpliedEnabledFeatures after D83273
Previously the time complexity is O(|number of paths from the root to an implied feature| * CPU_FWATURE_MAX) where CPU_FEATURE_MAX is 92. The number of paths can be large (theoretically exponential). For an inline asm statement, there is a code path `clang::Parser::ParseAsmStatement -> clang::Sema::ActOnGCCAsmStmt -> ASTContext::getFunctionFeatureMap` leading to potentially many calls of getImpliedEnabledFeatures (41 for my -march=native case). We should improve the performance a bit in case the number of inline asm statements is large (Linux kernel builds). Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D85257
1 parent 4c9ed3e commit 0c7af8c

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

llvm/lib/Support/X86TargetParser.cpp

+29-10
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class FeatureBitset {
3737
set(I);
3838
}
3939

40+
bool any() const {
41+
return llvm::any_of(Bits, [](uint64_t V) { return V != 0; });
42+
}
43+
4044
constexpr FeatureBitset &set(unsigned I) {
4145
// GCC <6.2 crashes if this is written in a single statement.
4246
uint32_t NewBits = Bits[I / 32] | (uint32_t(1) << (I % 32));
@@ -89,6 +93,13 @@ class FeatureBitset {
8993
Result.Bits[I] = ~Bits[I];
9094
return Result;
9195
}
96+
97+
constexpr bool operator!=(const FeatureBitset &RHS) const {
98+
for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I)
99+
if (Bits[I] != RHS.Bits[I])
100+
return true;
101+
return false;
102+
}
92103
};
93104

94105
struct ProcInfo {
@@ -552,24 +563,32 @@ void llvm::X86::getFeaturesForCPU(StringRef CPU,
552563
// For each feature that is (transitively) implied by this feature, set it.
553564
static void getImpliedEnabledFeatures(FeatureBitset &Bits,
554565
const FeatureBitset &Implies) {
566+
// Fast path: Implies is often empty.
567+
if (!Implies.any())
568+
return;
569+
FeatureBitset Prev;
555570
Bits |= Implies;
556-
for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i) {
557-
if (Implies[i])
558-
getImpliedEnabledFeatures(Bits, FeatureInfos[i].ImpliedFeatures);
559-
}
571+
do {
572+
Prev = Bits;
573+
for (unsigned i = CPU_FEATURE_MAX; i;)
574+
if (Bits[--i])
575+
Bits |= FeatureInfos[i].ImpliedFeatures;
576+
} while (Prev != Bits);
560577
}
561578

562579
/// Create bit vector of features that are implied disabled if the feature
563580
/// passed in Value is disabled.
564581
static void getImpliedDisabledFeatures(FeatureBitset &Bits, unsigned Value) {
565582
// Check all features looking for any dependent on this feature. If we find
566583
// one, mark it and recursively find any feature that depend on it.
567-
for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i) {
568-
if (FeatureInfos[i].ImpliedFeatures[Value]) {
569-
Bits.set(i);
570-
getImpliedDisabledFeatures(Bits, i);
571-
}
572-
}
584+
FeatureBitset Prev;
585+
Bits.set(Value);
586+
do {
587+
Prev = Bits;
588+
for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
589+
if ((FeatureInfos[i].ImpliedFeatures & Bits).any())
590+
Bits.set(i);
591+
} while (Prev != Bits);
573592
}
574593

575594
void llvm::X86::getImpliedFeatures(

0 commit comments

Comments
 (0)