[clang] [clang][Basic] Optimize getDiagnosticSeverity() (PR #141950)
Volodymyr Sapsai via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 17 17:07:37 PST 2026
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/141950 at github.com>
vsapsai wrote:
I'd like to report that this change causes a significant (sub-second -> multiple seconds) compilation time regression for the code like
```
#define EMPTY()
#define DEFER1(id) id EMPTY()
#define DEFER2(id) id EMPTY EMPTY()()
#define DEFER3(id) id EMPTY EMPTY EMPTY()()()
#define DEFER4(id) id EMPTY EMPTY EMPTY EMPTY()()()()
#define DEFER5(id) id EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()
#define DEFER6(id) id EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()()
#define DEFER7(id) id EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()()()
#define DEFER8(id) id EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()()()()
#define EVAL(...) EVAL1024(__VA_ARGS__)
#define EVAL1024(...) EVAL512(EVAL512(__VA_ARGS__))
#define EVAL512(...) EVAL256(EVAL256(__VA_ARGS__))
#define EVAL256(...) EVAL128(EVAL128(__VA_ARGS__))
#define EVAL128(...) EVAL64(EVAL64(__VA_ARGS__))
#define EVAL64(...) EVAL32(EVAL32(__VA_ARGS__))
#define EVAL32(...) EVAL16(EVAL16(__VA_ARGS__))
#define EVAL16(...) EVAL8(EVAL8(__VA_ARGS__))
#define EVAL8(...) EVAL4(EVAL4(__VA_ARGS__))
#define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__))
#define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__))
#define EVAL1(...) __VA_ARGS__
#define CAT(a, ...) a ## __VA_ARGS__
#define CAT3(a, b, ...) a ## b ## __VA_ARGS__
#define FIRST(a, ...) a
#define SECOND(a, b, ...) b
#define IS_PROBE(...) SECOND(__VA_ARGS__, 0)
#define PROBE() ~, 1
#define NOT(x) IS_PROBE(CAT(_NOT_, x))
#define _NOT_0 PROBE()
#define BOOLIFY(x) NOT(NOT(x))
#define HAS_ARGS(...) BOOLIFY(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)(0))
#define _END_OF_ARGUMENTS_(...) BOOLIFY(FIRST(__VA_ARGS__))
#define IF(c) _IF(BOOLIFY(c))
#define _IF(c) CAT(_IF_,c)
#define _IF_0(...)
#define _IF_1(...) __VA_ARGS__
#define MAP(...) \
IF(HAS_ARGS(__VA_ARGS__))(EVAL(MAP_INNER(__VA_ARGS__)))
#define MAP_INNER(op,sep,cur_val, ...) \
op(cur_val) \
IF(HAS_ARGS(__VA_ARGS__))( \
sep() DEFER2(_MAP_INNER)()(op, sep, ##__VA_ARGS__) \
)
#define _MAP_INNER() MAP_INNER
#define GENERATE_FUNCTIONS(type) /*
*/ void slow_compile_##type##_fn01(void) {} /*
*/ void slow_compile_##type##_fn02(void) {} /*
*/ void slow_compile_##type##_fn03(void) {} /*
*/ void slow_compile_##type##_fn04(void) {} /*
*/ void slow_compile_##type##_fn05(void) {} /*
*/ void slow_compile_##type##_fn06(void) {} /*
*/ void slow_compile_##type##_fn07(void) {} /*
*/ void slow_compile_##type##_fn08(void) {}
MAP(GENERATE_FUNCTIONS, EMPTY,
char, short, int, long
)
```
The reason for that is that with this change we are calling `SourceManager::isInSystemMacro` more often which leads to the following call chain
```
SourceManager::isInSystemMacro
getSpellingLoc
SourceManager::getSpellingLocSlowCase
SourceManager::getDecomposedLoc
getFileID(SourceLocation::UIntTy SLocOffset)
getFileIDSlow
SourceManager::getFileIDLocal
```
And when we have non-trivial macro expansions `createMacroArgExpansionLoc` is called multiple times causing `LocalLocOffsetTable` to grow to ~ 140'000 items. As the result `getFileIDLocal` gets pretty expensive and calling it [in GetDiagnosticSeverity] becomes prohibitively slow.
https://github.com/llvm/llvm-project/pull/141950
More information about the cfe-commits
mailing list