From e0582e69f517c5d4a47f52130ae4bd066c3d8edd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 10 Oct 2021 21:21:27 -0700 Subject: [PATCH] [TypeSwitch/Compiler.h] Provide a LLVM_NODEBUG macro and use it in TypeSwitch.h TypeSwitch.h is used pervasively in MLIR and often has dozens of types switched over. It uses "zero cost" variadic templates to implement the dispatching mechanism... which isn't zero cost in debug builds, and which causes a massive problem for actually debugging things that use it - you get dozens of nonsense frames in the debugger for simple things like a visitor. Fix this by marking the key method in TypeSwitch as nodebug + alwaysinline. This resolves LLVM PR49301 Differential Revision: https://reviews.llvm.org/D111520 --- llvm/include/llvm/ADT/TypeSwitch.h | 7 ++++++- llvm/include/llvm/Support/Compiler.h | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ADT/TypeSwitch.h b/llvm/include/llvm/ADT/TypeSwitch.h index 815b9a4..3b7598f 100644 --- a/llvm/include/llvm/ADT/TypeSwitch.h +++ b/llvm/include/llvm/ADT/TypeSwitch.h @@ -35,7 +35,12 @@ public: /// Invoke a case on the derived class with multiple case types. template - DerivedT &Case(CallableT &&caseFn) { + // This is marked always_inline and nodebug so it doesn't show up in stack + // traces at -O0 (or other optimization levels). Large TypeSwitch's are + // common, are equivalent to a switch, and don't add any value to stack + // traces. + LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG DerivedT & + Case(CallableT &&caseFn) { DerivedT &derived = static_cast(*this); return derived.template Case(caseFn) .template Case(caseFn); diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h index 3f7a77b..0158872 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h @@ -248,6 +248,15 @@ #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline #endif +/// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do +/// so, mark a method "no debug" because debug info makes the debugger +/// experience worse. GCC introduced this in GCC 4.0 +#if __has_attribute(nodebug) || LLVM_GNUC_PREREQ(4, 0, 0) +#define LLVM_ATTRIBUTE_NODEBUG __attribute__((nodebug)) +#else +#define LLVM_ATTRIBUTE_NODEBUG +#endif + #if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0) #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #elif defined(_MSC_VER) -- 2.7.4