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 @@ -325,6 +325,9 @@ /// emitted. VALUE_CODEGENOPT(DwarfVersion, 3, 0) +/// Whether to use experimental new variable location tracking. +CODEGENOPT(ValueTrackingVariableLocations, 1, 0) + /// Whether we should emit CodeView debug information. It's possible to emit /// CodeView and DWARF into the same object. CODEGENOPT(EmitCodeView, 1, 0) 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 @@ -3870,6 +3870,9 @@ HelpText<"Prints debug information for the new pass manager">; def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">, HelpText<"Disables debug printing for the new pass manager">; +def fexperimental_debug_variable_locations : Flag<["-"], + "fexperimental-debug-variable-locations">, + HelpText<"Use experimental new value-tracking variable locations">; // The driver option takes the key as a parameter to the -msign-return-address= // and -mbranch-protection= options, but CC1 has a separate option so we // don't have to parse the parameter twice. 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 @@ -520,6 +520,8 @@ Options.EmitAddrsig = CodeGenOpts.Addrsig; Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection; Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo; + Options.ValueTrackingVariableLocations = + CodeGenOpts.ValueTrackingVariableLocations; Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex; Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -835,6 +835,9 @@ llvm::is_contained(DebugEntryValueArchs, T.getArch())) Opts.EmitCallSiteInfo = true; + Opts.ValueTrackingVariableLocations = + Args.hasArg(OPT_fexperimental_debug_variable_locations); + Opts.DisableO0ImplyOptNone = Args.hasArg(OPT_disable_O0_optnone); Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone); Opts.IndirectTlsSegRefs = Args.hasArg(OPT_mno_tls_direct_seg_refs); diff --git a/clang/test/Driver/debug-var-experimental-switch.c b/clang/test/Driver/debug-var-experimental-switch.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/debug-var-experimental-switch.c @@ -0,0 +1,2 @@ +// RUN: %clang -Xclang -fexperimental-debug-variable-locations -fsyntax-only -disable-llvm-passes %s +int main() {} diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h --- a/llvm/include/llvm/CodeGen/CommandFlags.h +++ b/llvm/include/llvm/CodeGen/CommandFlags.h @@ -116,6 +116,8 @@ bool getEnableDebugEntryValues(); +bool getValueTrackingVariableLocations(); + bool getForceDwarfFrameSection(); bool getXRayOmitFunctionIndex(); diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -126,8 +126,8 @@ EmitStackSizeSection(false), EnableMachineOutliner(false), SupportsDefaultOutlining(false), EmitAddrsig(false), EmitCallSiteInfo(false), SupportsDebugEntryValues(false), - EnableDebugEntryValues(false), ForceDwarfFrameSection(false), - XRayOmitFunctionIndex(false), + EnableDebugEntryValues(false), ValueTrackingVariableLocations(false), + ForceDwarfFrameSection(false), XRayOmitFunctionIndex(false), FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {} /// DisableFramePointerElim - This returns true if frame pointer elimination @@ -285,6 +285,11 @@ /// production. bool ShouldEmitDebugEntryValues() const; + // When set to true, use experimental new debug variable location tracking, + // which seeks to follow the values of variables rather than their location, + // post isel. + unsigned ValueTrackingVariableLocations : 1; + /// Emit DWARF debug frame section. unsigned ForceDwarfFrameSection : 1; diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp --- a/llvm/lib/CodeGen/CommandFlags.cpp +++ b/llvm/lib/CodeGen/CommandFlags.cpp @@ -85,6 +85,7 @@ CGOPT(bool, EnableAddrsig) CGOPT(bool, EmitCallSiteInfo) CGOPT(bool, EnableDebugEntryValues) +CGOPT(bool, ValueTrackingVariableLocations) CGOPT(bool, ForceDwarfFrameSection) CGOPT(bool, XRayOmitFunctionIndex) @@ -400,6 +401,12 @@ cl::init(false)); CGBINDOPT(EnableDebugEntryValues); + static cl::opt ValueTrackingVariableLocations( + "experimental-debug-variable-locations", + cl::desc("Use experimental new value-tracking variable locations"), + cl::init(false)); + CGBINDOPT(ValueTrackingVariableLocations); + static cl::opt ForceDwarfFrameSection( "force-dwarf-frame-section", cl::desc("Always emit a debug frame section."), cl::init(false)); @@ -475,6 +482,7 @@ Options.EmitAddrsig = getEnableAddrsig(); Options.EmitCallSiteInfo = getEmitCallSiteInfo(); Options.EnableDebugEntryValues = getEnableDebugEntryValues(); + Options.ValueTrackingVariableLocations = getValueTrackingVariableLocations(); Options.ForceDwarfFrameSection = getForceDwarfFrameSection(); Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex(); diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp @@ -14,6 +14,7 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" +#include "llvm/Target/TargetMachine.h" /// \file LiveDebugValues.cpp /// @@ -40,7 +41,10 @@ static char ID; LiveDebugValues(); - ~LiveDebugValues() { delete TheImpl; } + ~LiveDebugValues() { + if (TheImpl) + delete TheImpl; + } /// Calculate the liveness information for the given machine function. bool runOnMachineFunction(MachineFunction &MF) override; @@ -57,6 +61,7 @@ private: LDVImpl *TheImpl; + TargetPassConfig *TPC; }; char LiveDebugValues::ID = 0; @@ -69,10 +74,24 @@ /// Default construct and initialize the pass. LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) { initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry()); - TheImpl = llvm::makeVarLocBasedLiveDebugValues(); + TheImpl = nullptr; } bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) { - auto *TPC = getAnalysisIfAvailable(); + if (!TheImpl) { + TPC = getAnalysisIfAvailable(); + + bool InstrRefBased = false; + if (TPC) { + auto &TM = TPC->getTM(); + InstrRefBased = TM.Options.ValueTrackingVariableLocations; + } + + if (InstrRefBased) + TheImpl = llvm::makeInstrRefBasedLiveDebugValues(); + else + TheImpl = llvm::makeVarLocBasedLiveDebugValues(); + } + return TheImpl->ExtendRanges(MF, TPC); }