[llvm] 0116ed0 - [DebugInfo][InstrRef] Don't use instr-ref for unoptimised functions

Jeremy Morse via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 25 07:10:53 PDT 2021


Author: Jeremy Morse
Date: 2021-08-25T15:10:36+01:00
New Revision: 0116ed006929224a934d99bd3705812485969221

URL: https://github.com/llvm/llvm-project/commit/0116ed006929224a934d99bd3705812485969221
DIFF: https://github.com/llvm/llvm-project/commit/0116ed006929224a934d99bd3705812485969221.diff

LOG: [DebugInfo][InstrRef] Don't use instr-ref for unoptimised functions

InstrRefBasedLDV is marginally slower than VarlocBasedLDV when analysing
optimised code -- however, it's much slower when analysing code compiled
-O0.

To avoid this: don't use instruction referencing for -O0 functions. In the
"pure" case of unoptimised code, this won't really harm the debugging
experience because most variables won't have been promoted off the stack,
so can't go missing. It becomes more complicated when optimised code is
inlined into functions marked optnone; however these are rare, and as -O0
doesn't run many optimisations there should be little damage to the debug
experience as a result.

I've taken the opportunity to refactor testing for instruction-referencing
into a MachineFunction method, which seems the most appropriate place to
put it.

Differential Revision: https://reviews.llvm.org/D108585

Added: 
    llvm/test/DebugInfo/X86/instr-ref-opt-levels.ll

Modified: 
    llvm/include/llvm/CodeGen/MachineFunction.h
    llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
    llvm/lib/CodeGen/LiveDebugVariables.cpp
    llvm/lib/CodeGen/MachineFunction.cpp
    llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 786fe908f68f..85016fc7d415 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -536,6 +536,10 @@ class MachineFunction {
   /// (or DBG_PHI).
   void finalizeDebugInstrRefs();
 
+  /// Returns true if the function's variable locations should be tracked with
+  /// instruction referencing.
+  bool useDebugInstrRef() const;
+
   MachineFunction(Function &F, const LLVMTargetMachine &Target,
                   const TargetSubtargetInfo &STI, unsigned FunctionNum,
                   MachineModuleInfo &MMI);

diff  --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
index bc1eaff60440..07dba303e67b 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
@@ -99,12 +99,7 @@ LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
 bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
   if (!TheImpl) {
     TPC = getAnalysisIfAvailable<TargetPassConfig>();
-
-    bool InstrRefBased = false;
-    if (TPC) {
-      auto &TM = TPC->getTM<TargetMachine>();
-      InstrRefBased = TM.Options.ValueTrackingVariableLocations;
-    }
+    bool InstrRefBased = MF.useDebugInstrRef();
 
     // Allow the user to force selection of InstrRef LDV.
     InstrRefBased |= ForceInstrRefLDV;

diff  --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 54058a547928..9a86cc78cd57 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -1314,12 +1314,7 @@ bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) {
 
   // Have we been asked to track variable locations using instruction
   // referencing?
-  bool InstrRef = false;
-  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
-  if (TPC) {
-    auto &TM = TPC->getTM<TargetMachine>();
-    InstrRef = TM.Options.ValueTrackingVariableLocations;
-  }
+  bool InstrRef = mf.useDebugInstrRef();
 
   if (!pImpl)
     pImpl = new LDVImpl(this);

diff  --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 88dc5a6544a7..7da58fd0f809 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -1174,7 +1174,7 @@ void MachineFunction::finalizeDebugInstrRefs() {
     MI.getOperand(0).setIsDebug();
   };
 
-  if (!getTarget().Options.ValueTrackingVariableLocations)
+  if (!useDebugInstrRef())
     return;
 
   for (auto &MBB : *this) {
@@ -1221,6 +1221,24 @@ void MachineFunction::finalizeDebugInstrRefs() {
   }
 }
 
+bool MachineFunction::useDebugInstrRef() const {
+  // Disable instr-ref at -O0: it's very slow (in compile time). We can still
+  // have optimized code inlined into this unoptimized code, however with
+  // fewer and less aggressive optimizations happening, coverage and accuracy
+  // should not suffer.
+  if (getTarget().getOptLevel() == CodeGenOpt::None)
+    return false;
+
+  // Don't use instr-ref if this function is marked optnone.
+  if (F.hasFnAttribute(Attribute::OptimizeNone))
+    return false;
+
+  if (getTarget().Options.ValueTrackingVariableLocations)
+    return true;
+
+  return false;
+}
+
 /// \}
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 89dacd2b498d..f350354075da 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1264,7 +1264,7 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
       // If using instruction referencing, mutate this into a DBG_INSTR_REF,
       // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto
       // the expression, we don't have an "indirect" flag in DBG_INSTR_REF.
-      if (TM.Options.ValueTrackingVariableLocations && Op->isReg()) {
+      if (FuncInfo.MF->useDebugInstrRef() && Op->isReg()) {
         Builder->setDesc(TII.get(TargetOpcode::DBG_INSTR_REF));
         Builder->getOperand(1).ChangeToImmediate(0);
         auto *NewExpr =
@@ -1323,7 +1323,7 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
 
       // If using instruction referencing, mutate this into a DBG_INSTR_REF,
       // to be later patched up by finalizeDebugInstrRefs.
-      if (TM.Options.ValueTrackingVariableLocations) {
+      if (FuncInfo.MF->useDebugInstrRef()) {
         Builder->setDesc(TII.get(TargetOpcode::DBG_INSTR_REF));
         Builder->getOperand(1).ChangeToImmediate(0);
       }

diff  --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 195aa14c0a96..02cccdcaea22 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -1340,5 +1340,5 @@ InstrEmitter::InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb,
       TRI(MF->getSubtarget().getRegisterInfo()),
       TLI(MF->getSubtarget().getTargetLowering()), MBB(mbb),
       InsertPos(insertpos) {
-  EmitDebugInstrRefs = TM.Options.ValueTrackingVariableLocations;
+  EmitDebugInstrRefs = MF->useDebugInstrRef();
 }

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 4286be5a1559..fd31078e640a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5515,7 +5515,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
   // we've been asked to pursue.
   auto MakeVRegDbgValue = [&](Register Reg, DIExpression *FragExpr,
                               bool Indirect) {
-    if (Reg.isVirtual() && TM.Options.ValueTrackingVariableLocations) {
+    if (Reg.isVirtual() && MF.useDebugInstrRef()) {
       // For VRegs, in instruction referencing mode, create a DBG_INSTR_REF
       // pointing at the VReg, which will be patched up later.
       auto &Inst = TII->get(TargetOpcode::DBG_INSTR_REF);

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index a475ce60cca7..3bd5db4e09b0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -575,7 +575,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
         LiveInMap.insert(LI);
 
   // Insert DBG_VALUE instructions for function arguments to the entry block.
-  bool InstrRef = TM.Options.ValueTrackingVariableLocations;
+  bool InstrRef = MF->useDebugInstrRef();
   for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) {
     MachineInstr *MI = FuncInfo->ArgDbgValues[e - i - 1];
     assert(MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST &&

diff  --git a/llvm/test/DebugInfo/X86/instr-ref-opt-levels.ll b/llvm/test/DebugInfo/X86/instr-ref-opt-levels.ll
new file mode 100644
index 000000000000..2a4fd334f2fa
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/instr-ref-opt-levels.ll
@@ -0,0 +1,73 @@
+; RUN: llc -mtriple=x86_64-- %s -o - -O0 -stop-before=finalize-isel \
+; RUN:      -experimental-debug-variable-locations \
+; RUN:    | FileCheck %s --check-prefix=O0 --implicit-check-not=DBG_INSTR_REF
+; RUN: llc -mtriple=x86_64-- %s -o - -O2 -stop-before=finalize-isel \
+; RUN:      -experimental-debug-variable-locations \
+; RUN:    | FileCheck %s --check-prefix=O2 --implicit-check-not=DBG_VALUE
+; RUN: llc -mtriple=x86_64-- %s -o - -stop-before=finalize-isel \
+; RUN:      -fast-isel -experimental-debug-variable-locations \
+; RUN:    | FileCheck %s --check-prefix=FASTISEL --implicit-check-not=DBG_VALUE
+
+; Test that instruction-referencing variable locations are issued at -O2, but
+; normal DBG_VALUEs are issued at -O0. This behaviour is desired as the former
+; is slow when applied to unoptimized code.
+; (Copy + pasted from ./dead-store-elimination-marks-undef.ll),
+
+; O0-LABEL: name: main
+; O0:       DBG_VALUE
+; O0-LABEL: name: fn_optnone
+; O0:       DBG_VALUE
+
+; O2-LABEL: name: main
+; O2:       DBG_INSTR_REF
+; O2-LABEL: name: fn_optnone
+; O2:       DBG_VALUE
+
+; FASTISEL-LABEL: name: main
+; FASTISEL:       DBG_INSTR_REF
+; FASTISEL-LABEL: name: fn_optnone
+; FASTISEL:       DBG_VALUE
+
+ at b = common dso_local local_unnamed_addr global i32 0, align 1
+
+define dso_local i32 @main() local_unnamed_addr !dbg !7 {
+  %1 = alloca i32, align 4
+  %2 = load i32, i32* @b, align 1, !dbg !13
+  call void @llvm.dbg.value(metadata i32 %2, metadata !12, metadata !DIExpression()), !dbg !13
+  store i32 %2, i32* %1, align 4, !dbg !13
+  ret i32 0, !dbg !13
+}
+
+define dso_local i32 @fn_optnone() local_unnamed_addr #0 !dbg !27 {
+  %1 = alloca i32, align 4
+  %2 = load i32, i32* @b, align 1, !dbg !33
+  call void @llvm.dbg.value(metadata i32 %2, metadata !32, metadata !DIExpression()), !dbg !33
+  store i32 %2, i32* %1, align 4, !dbg !33
+  ret i32 0, !dbg !33
+}
+
+attributes #0 = {optnone noinline}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, nameTableKind: None)
+!1 = !DIFile(filename: "dead-store-elimination-marks-undef.ll", directory: "/temp/bz45080")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!6 = !{!"clang version 10.0.0"}
+!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "l_2864", scope: !7, file: !1, line: 4, type: !10)
+!13 = !DILocation(line: 5, column: 12, scope: !7)
+!27 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !31)
+!31 = !{!32}
+!32 = !DILocalVariable(name: "l_2864", scope: !27, file: !1, line: 4, type: !10)
+!33 = !DILocation(line: 5, column: 12, scope: !27)


        


More information about the llvm-commits mailing list