From 984de46013b14bec9c3759ef47a853940306ceca Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Fri, 18 Jul 2025 13:34:07 +0100 Subject: [PATCH 1/2] [KeyInstr] Enable -gkey-instructions by default if optimisations are enabled Key Instructions improves the optimized-code debug-stepping experience in debuggers that use DWARF's `is_stmt` line table register to determine stepping behaviour. The feature can be disabled with `-gno-key-instructions`. RFC: https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668 --- clang/lib/Driver/ToolChains/Clang.cpp | 8 ++++- clang/test/DebugInfo/KeyInstructions/flag.cpp | 33 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8880c9375143f..38eebbd6f9b5f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4611,8 +4611,14 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, CmdArgs.push_back("-gembed-source"); } + // Enable Key Instructions by default if optimisations are enabled and + // we're emitting DWARF. + Arg *OptLevel = Args.getLastArg(options::OPT_O_Group); + bool KeyInstructionsOnByDefault = + EmitDwarf && OptLevel && !OptLevel->getOption().matches(options::OPT_O0); if (Args.hasFlag(options::OPT_gkey_instructions, - options::OPT_gno_key_instructions, false)) + options::OPT_gno_key_instructions, + KeyInstructionsOnByDefault)) CmdArgs.push_back("-gkey-instructions"); if (EmitCodeView) { diff --git a/clang/test/DebugInfo/KeyInstructions/flag.cpp b/clang/test/DebugInfo/KeyInstructions/flag.cpp index e34faa6cbb347..05a34ac670feb 100644 --- a/clang/test/DebugInfo/KeyInstructions/flag.cpp +++ b/clang/test/DebugInfo/KeyInstructions/flag.cpp @@ -1,7 +1,5 @@ // RUN: %clang -### -target x86_64 -c -gdwarf -gkey-instructions %s 2>&1 | FileCheck %s --check-prefixes=KEY-INSTRUCTIONS // RUN: %clang -### -target x86_64 -c -gdwarf -gno-key-instructions %s 2>&1 | FileCheck %s --check-prefixes=NO-KEY-INSTRUCTIONS -//// Default: Off. -// RUN: %clang -### -target x86_64 -c -gdwarf %s 2>&1 | FileCheck %s --check-prefixes=NO-KEY-INSTRUCTIONS //// Help. // RUN %clang --help | FileCheck %s --check-prefix=HELP @@ -23,3 +21,34 @@ void f() {} // RUN: %clang_cc1 %s -triple x86_64-linux-gnu -gkey-instructions -debug-info-kind=line-tables-only -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-ON // SMOKETEST-ON: keyInstructions: true // SMOKETEST-ON: atomGroup: 1 + +//// Enable Key Instructions by default if optimisations are enabled and we're +//// emitting DWARF. +//// +//// | opt level | -gkey-instructions | feature | +//// | 0 | no | off | +//// | 0 | yes | on | +//// | >=1 | no | on | +//// | >=1 | yes | on | +//// | >=1 | no & no -g flags | off | +//// | >=1 | no & emit codeview | off | +// +// RUN: %clang %s -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS +// RUN: %clang %s -target x86_64 -gdwarf -gmlt -gkey-instructions -### 2>&1 | FileCheck %s --check-prefix=KEY-INSTRUCTIONS +// RUN: %clang %s -O0 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS +// RUN: %clang %s -O0 -target x86_64 -gdwarf -gmlt -gkey-instructions -### 2>&1 | FileCheck %s --check-prefix=KEY-INSTRUCTIONS +// RUN: %clang %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=KEY-INSTRUCTIONS +// RUN: %clang %s -O1 -target x86_64 -gdwarf -gmlt -gkey-instructions -### 2>&1 | FileCheck %s --check-prefix=KEY-INSTRUCTIONS +// RUN: %clang %s -O1 -target x86_64 -### 2>&1 | FileCheck %s --check-prefixes=NO-KEY-INSTRUCTIONS +// RUN: %clang %s -O1 -target x86_64 -gcodeview -gmlt -### 2>&1 | FileCheck %s --check-prefixes=NO-KEY-INSTRUCTIONS +// +// RUN: %clang %s -target x86_64 -gdwarf -gmlt -S -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-OFF +// RUN: %clang %s -target x86_64 -gdwarf -gmlt -gkey-instructions -S -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-ON +// RUN: %clang %s -O0 -target x86_64 -gdwarf -gmlt -S -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-OFF +// RUN: %clang %s -O0 -target x86_64 -gdwarf -gmlt -gkey-instructions -S -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-ON +// RUN: %clang %s -O1 -target x86_64 -gdwarf -gmlt -S -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-ON +// RUN: %clang %s -O1 -target x86_64 -gdwarf -gmlt -gkey-instructions -S -emit-llvm -o - | FileCheck %s --check-prefix=SMOKETEST-ON +// RUN: %clang %s -O1 -target x86_64 -S -emit-llvm -o - | FileCheck %s --check-prefixes=SMOKETEST-OFF,SMOKETEST-NO-DEBUG +// RUN: %clang %s -O1 -target x86_64 -gcodeview -gmlt -S -emit-llvm -o - | FileCheck %s --check-prefixes=SMOKETEST-OFF +// SMOKETEST-NO-DEBUG: llvm.module.flags +// SMOKETEST-NO-DEBUG-NOT: DICompileUnit From 9a6d8b247e2c62daa4edbd9e37ac91178a80b17c Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 26 Aug 2025 10:36:15 +0100 Subject: [PATCH 2/2] Only enable for 'plain' C/C++ --- clang/lib/Driver/ToolChains/Clang.cpp | 20 ++++++++++++------- clang/test/DebugInfo/KeyInstructions/flag.cpp | 9 +++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 38eebbd6f9b5f..75e7e3badf309 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4414,10 +4414,15 @@ static void renderDwarfFormat(const Driver &D, const llvm::Triple &T, static void renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, - const ArgList &Args, bool IRInput, ArgStringList &CmdArgs, - const InputInfo &Output, + const ArgList &Args, types::ID InputType, + ArgStringList &CmdArgs, const InputInfo &Output, llvm::codegenoptions::DebugInfoKind &DebugInfoKind, DwarfFissionKind &DwarfFission) { + bool IRInput = isLLVMIR(InputType); + bool PlainCOrCXX = isDerivedFromC(InputType) && !isCuda(InputType) && + !isHIP(InputType) && !isObjC(InputType) && + !isOpenCL(InputType); + if (Args.hasFlag(options::OPT_fdebug_info_for_profiling, options::OPT_fno_debug_info_for_profiling, false) && checkDebugInfoOption( @@ -4611,11 +4616,12 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, CmdArgs.push_back("-gembed-source"); } - // Enable Key Instructions by default if optimisations are enabled and - // we're emitting DWARF. + // Enable Key Instructions by default if we're emitting DWARF, the language is + // plain C or C++, and optimisations are enabled. Arg *OptLevel = Args.getLastArg(options::OPT_O_Group); bool KeyInstructionsOnByDefault = - EmitDwarf && OptLevel && !OptLevel->getOption().matches(options::OPT_O0); + EmitDwarf && PlainCOrCXX && OptLevel && + !OptLevel->getOption().matches(options::OPT_O0); if (Args.hasFlag(options::OPT_gkey_instructions, options::OPT_gno_key_instructions, KeyInstructionsOnByDefault)) @@ -6085,8 +6091,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, llvm::codegenoptions::DebugInfoKind DebugInfoKind = llvm::codegenoptions::NoDebugInfo; DwarfFissionKind DwarfFission = DwarfFissionKind::None; - renderDebugOptions(TC, D, RawTriple, Args, types::isLLVMIR(InputType), - CmdArgs, Output, DebugInfoKind, DwarfFission); + renderDebugOptions(TC, D, RawTriple, Args, InputType, CmdArgs, Output, + DebugInfoKind, DwarfFission); // Add the split debug info name to the command lines here so we // can propagate it to the backend. diff --git a/clang/test/DebugInfo/KeyInstructions/flag.cpp b/clang/test/DebugInfo/KeyInstructions/flag.cpp index 05a34ac670feb..a5cd8558eae52 100644 --- a/clang/test/DebugInfo/KeyInstructions/flag.cpp +++ b/clang/test/DebugInfo/KeyInstructions/flag.cpp @@ -52,3 +52,12 @@ void f() {} // RUN: %clang %s -O1 -target x86_64 -gcodeview -gmlt -S -emit-llvm -o - | FileCheck %s --check-prefixes=SMOKETEST-OFF // SMOKETEST-NO-DEBUG: llvm.module.flags // SMOKETEST-NO-DEBUG-NOT: DICompileUnit + +//// Check only "plain" C/C++ turns on Key Instructions by default. +// RUN: %clang -x c %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=KEY-INSTRUCTIONS +// RUN: %clang -x c++ %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=KEY-INSTRUCTIONS +// RUN: %clang -x cuda -nocudalib -nocudainc %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS +// RUN: %clang -x hip -nogpulib -nogpuinc %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS +// RUN: %clang -x cl %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS +// RUN: %clang -x objective-c %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS +// RUN: %clang -x objective-c++ %s -O1 -target x86_64 -gdwarf -gmlt -### 2>&1 | FileCheck %s --check-prefix=NO-KEY-INSTRUCTIONS