diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -163,6 +163,12 @@ Never, // No loop is assumed to be finite. }; + enum AssignmentTrackingOpts { + Disabled, + Enabled, + Forced, + }; + /// The code model to use (-mcmodel). std::string CodeModel; diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -335,8 +335,8 @@ CODEGENOPT(NoStackArgProbe, 1, 0) ///< Set when -mno-stack-arg-probe is used CODEGENOPT(DebugStrictDwarf, 1, 1) ///< Whether or not to use strict DWARF info. -CODEGENOPT(EnableAssignmentTracking, 1,0) ///< Enable the Assignment Tracking - ///< debug info feature. +/// Control the Assignment Tracking debug info feature. +ENUM_CODEGENOPT(AssignmentTrackingMode, AssignmentTrackingOpts, 2, AssignmentTrackingOpts::Disabled) CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information ///< in debug info. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5796,11 +5796,11 @@ "and non-deleting destructors. (No effect on Microsoft ABI)">, MarshallingInfoFlag>; -defm experimental_assignment_tracking : - BoolOption<"f", "experimental-assignment-tracking", - CodeGenOpts<"EnableAssignmentTracking">, DefaultFalse, - PosFlag, NegFlag, BothFlags<[CoreOption]>>, - Group; +def experimental_assignment_tracking_EQ : Joined<["-"], "fexperimental-assignment-tracking=">, + Group, CodeGenOpts<"EnableAssignmentTracking">, + NormalizedValuesScope<"CodeGenOptions::AssignmentTrackingOpts">, + Values<"disabled,enabled,forced">, NormalizedValues<["Disabled","Enabled","Forced"]>, + MarshallingInfoEnum, "Disabled">; } // let Flags = [CC1Option, NoDriverOption] diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -840,11 +840,29 @@ SI.registerCallbacks(PIC, &MAM); PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC); - if (CodeGenOpts.EnableAssignmentTracking) { + // Handle the assignment tracking feature options. + switch (CodeGenOpts.getAssignmentTrackingMode()) { + case CodeGenOptions::AssignmentTrackingOpts::Forced: PB.registerPipelineStartEPCallback( [&](ModulePassManager &MPM, OptimizationLevel Level) { MPM.addPass(AssignmentTrackingPass()); }); + break; + case CodeGenOptions::AssignmentTrackingOpts::Enabled: + // Disable assignment tracking in LTO builds for now as the performance + // cost is too high. Disable for LLDB tuning due to llvm.org/PR43126. + if (!CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.PrepareForLTO && + CodeGenOpts.getDebuggerTuning() != llvm::DebuggerKind::LLDB) { + PB.registerPipelineStartEPCallback( + [&](ModulePassManager &MPM, OptimizationLevel Level) { + // Only use assignment tracking if optimisations are enabled. + if (Level != OptimizationLevel::O0) + MPM.addPass(AssignmentTrackingPass()); + }); + } + break; + case CodeGenOptions::AssignmentTrackingOpts::Disabled: + break; } // Enable verify-debuginfo-preserve-each for new PM. diff --git a/clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp b/clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp --- a/clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp +++ b/clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \ -// RUN: -emit-llvm -fexperimental-assignment-tracking %s -o - \ +// RUN: -emit-llvm -fexperimental-assignment-tracking=forced %s -o - \ // RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg" // Based on llvm/test/DebugInfo/Generic/track-assignments.ll - check that using diff --git a/clang/test/CodeGen/assignment-tracking/flag.cpp b/clang/test/CodeGen/assignment-tracking/flag.cpp --- a/clang/test/CodeGen/assignment-tracking/flag.cpp +++ b/clang/test/CodeGen/assignment-tracking/flag.cpp @@ -1,24 +1,64 @@ //// Explicitly enabled: -// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \ -// RUN: -emit-llvm -fexperimental-assignment-tracking %s -o - \ +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm -fexperimental-assignment-tracking=enabled %s -o - -O1 \ // RUN: | FileCheck %s --check-prefixes=ENABLE + +//// Explicitly disabled: +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=disabled -O1\ +// RUN: | FileCheck %s --check-prefixes=DISABLE + //// Disabled by default: -// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \ -// RUN: -emit-llvm %s -o - \ +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -O1 \ // RUN: | FileCheck %s --check-prefixes=DISABLE -//// Explicitly disabled: -// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \ -// RUN: -emit-llvm %s -o - -fno-experimental-assignment-tracking \ + +//// Disabled at O0 unless forced. +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=enabled \ +// RUN: -O0 \ +// RUN: | FileCheck %s --check-prefixes=DISABLE +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=forced \ +// RUN: -O0 \ +// RUN: | FileCheck %s --check-prefixes=ENABLE + +//// Disabled for LTO and thinLTO unless forced. +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=enabled \ +// RUN: -O1 -flto=full \ // RUN: | FileCheck %s --check-prefixes=DISABLE +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=enabled \ +// RUN: -O1 -flto=thin \ +// RUN: | FileCheck %s --check-prefixes=DISABLE +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=forced \ +// RUN: -O1 -flto=full \ +// RUN: | FileCheck %s --check-prefixes=ENABLE +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=forced \ +// RUN: -O1 -flto=thin \ +// RUN: | FileCheck %s --check-prefixes=ENABLE -// Check some assignment-tracking stuff appears in the output when the flag -// -fexperimental-assignment-tracking is used, that it doesn't when -// -fno-experimental-assignment-tracking is used or neither flag is specified. +//// Disabled for LLDB debugger tuning unless forced. +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=enabled \ +// RUN: -O1 -debugger-tuning=lldb \ +// RUN: | FileCheck %s --check-prefixes=DISABLE +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone \ +// RUN: -emit-llvm %s -o - -fexperimental-assignment-tracking=forced \ +// RUN: -O1 -debugger-tuning=lldb \ +// RUN: | FileCheck %s --check-prefixes=ENABLE -// ENABLE: DIAssignID -// ENABLE: dbg.assign +// Check the assignment-tracking module flag appears in the output when the +// flag -fexperimental-assignment-tracking is set to 'enabled' (in some cases) +// or 'forced' (always), and is does not appear when the flag is set to +// 'disabled' (default). -// DISABLE-NOT: DIAssignID -// DISABLE-NOT: dbg.assign +// ENABLE: "debug-info-assignment-tracking" +// DISABLE-NOT: "debug-info-assignment-tracking" +//// Check there's actually any output at all. +// DISABLE: llvm.module.flags void fun(int a) {} diff --git a/clang/test/CodeGen/assignment-tracking/memcpy-fragment.cpp b/clang/test/CodeGen/assignment-tracking/memcpy-fragment.cpp --- a/clang/test/CodeGen/assignment-tracking/memcpy-fragment.cpp +++ b/clang/test/CodeGen/assignment-tracking/memcpy-fragment.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \ -// RUN: -emit-llvm -fexperimental-assignment-tracking %s -o - \ +// RUN: -emit-llvm -fexperimental-assignment-tracking=forced %s -o - \ // RUN: | FileCheck %s // Check that the (debug) codegen looks right with assignment tracking diff --git a/clang/test/CodeGen/assignment-tracking/nested-scope.cpp b/clang/test/CodeGen/assignment-tracking/nested-scope.cpp --- a/clang/test/CodeGen/assignment-tracking/nested-scope.cpp +++ b/clang/test/CodeGen/assignment-tracking/nested-scope.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \ -// RUN: -emit-llvm -fexperimental-assignment-tracking %s -o - \ +// RUN: -emit-llvm -fexperimental-assignment-tracking=forced %s -o - \ // RUN: | FileCheck %s // Check that dbg.assign intrinsics get a !dbg with with the same scope as