From a76db201adef70501ad0cf03614c0dd5924067d6 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 22 May 2017 20:47:09 +0000 Subject: [PATCH] Don't generate line&scope debug info for meta-instructions. MachineInstructions that don't generate any code (such as IMPLICIT_DEFs) should not generate any debug info either. Fixes PR33107. https://bugs.llvm.org/show_bug.cgi?id=33107 This reapplies r303566 without any modifications. The stage2 build failures persisted even after reverting this patch, and looking back through history, it looks like these tests are flaky. llvm-svn: 303575 --- include/llvm/CodeGen/MachineInstr.h | 37 +++--- lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 4 +- lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 6 +- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 4 +- lib/CodeGen/LexicalScopes.cpp | 5 +- test/DebugInfo/MIR/X86/empty-inline.mir | 122 ++++++++++++++++++++ 6 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 test/DebugInfo/MIR/X86/empty-inline.mir diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index e7e728c1be2..8d040beff7a 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -826,20 +826,12 @@ public: getOperand(0).getSubReg() == getOperand(1).getSubReg(); } - /// Return true if this is a transient instruction that is - /// either very likely to be eliminated during register allocation (such as - /// copy-like instructions), or if this instruction doesn't have an - /// execution-time cost. - bool isTransient() const { - switch(getOpcode()) { - default: return false; - // Copy-like instructions are usually eliminated during register allocation. - case TargetOpcode::PHI: - case TargetOpcode::COPY: - case TargetOpcode::INSERT_SUBREG: - case TargetOpcode::SUBREG_TO_REG: - case TargetOpcode::REG_SEQUENCE: - // Pseudo-instructions that don't produce any real output. + /// Return true if this instruction doesn't produce any output in the form of + /// executable instructions. + bool isMetaInstruction() const { + switch (getOpcode()) { + default: + return false; case TargetOpcode::IMPLICIT_DEF: case TargetOpcode::KILL: case TargetOpcode::CFI_INSTRUCTION: @@ -850,6 +842,23 @@ public: } } + /// Return true if this is a transient instruction that is either very likely + /// to be eliminated during register allocation (such as copy-like + /// instructions), or if this instruction doesn't have an execution-time cost. + bool isTransient() const { + switch (getOpcode()) { + default: + return isMetaInstruction(); + // Copy-like instructions are usually eliminated during register allocation. + case TargetOpcode::PHI: + case TargetOpcode::COPY: + case TargetOpcode::INSERT_SUBREG: + case TargetOpcode::SUBREG_TO_REG: + case TargetOpcode::REG_SEQUENCE: + return true; + } + } + /// Return the number of instructions inside the MI bundle, excluding the /// bundle header. /// diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 1b39e46ee46..881531078a5 100644 --- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1025,11 +1025,11 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) { bool EmptyPrologue = true; for (const auto &MBB : *MF) { for (const auto &MI : MBB) { - if (!MI.isDebugValue() && !MI.getFlag(MachineInstr::FrameSetup) && + if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) && MI.getDebugLoc()) { PrologEndLoc = MI.getDebugLoc(); break; - } else if (!MI.isDebugValue()) { + } else if (!MI.isMetaInstruction()) { EmptyPrologue = false; } } diff --git a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 826162ad47c..27ae77b18cd 100644 --- a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -223,9 +223,9 @@ void DebugHandlerBase::endInstruction() { return; assert(CurMI != nullptr); - // Don't create a new label after DBG_VALUE instructions. - // They don't generate code. - if (!CurMI->isDebugValue()) { + // Don't create a new label after DBG_VALUE and other instructions that don't + // generate code. + if (!CurMI->isMetaInstruction()) { PrevLabel = nullptr; PrevInstBB = CurMI->getParent(); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 3410b98d777..8fb3db274ec 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1029,7 +1029,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { assert(CurMI); // Check if source location changes, but ignore DBG_VALUE and CFI locations. - if (MI->isDebugValue() || MI->isCFIInstruction()) + if (MI->isMetaInstruction()) return; const DebugLoc &DL = MI->getDebugLoc(); // When we emit a line-0 record, we don't update PrevInstLoc; so look at @@ -1111,7 +1111,7 @@ static DebugLoc findPrologueEndLoc(const MachineFunction *MF) { // the beginning of the function body. for (const auto &MBB : *MF) for (const auto &MI : MBB) - if (!MI.isDebugValue() && !MI.getFlag(MachineInstr::FrameSetup) && + if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) && MI.getDebugLoc()) return MI.getDebugLoc(); return DebugLoc(); diff --git a/lib/CodeGen/LexicalScopes.cpp b/lib/CodeGen/LexicalScopes.cpp index 275d84e2c18..40ee7ea785f 100644 --- a/lib/CodeGen/LexicalScopes.cpp +++ b/lib/CodeGen/LexicalScopes.cpp @@ -86,8 +86,9 @@ void LexicalScopes::extractLexicalScopes( continue; } - // Ignore DBG_VALUE. It does not contribute to any instruction in output. - if (MInsn.isDebugValue()) + // Ignore DBG_VALUE and similar instruction that do not contribute to any + // instruction in the output. + if (MInsn.isMetaInstruction()) continue; if (RangeBeginMI) { diff --git a/test/DebugInfo/MIR/X86/empty-inline.mir b/test/DebugInfo/MIR/X86/empty-inline.mir new file mode 100644 index 00000000000..1766a8f4461 --- /dev/null +++ b/test/DebugInfo/MIR/X86/empty-inline.mir @@ -0,0 +1,122 @@ +# RUN: llc -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s +# +# This testcase has an implicit def pseudo-iunstruction with a debug location. +# +# CHECK: .debug_info contents: +# CHECK: DW_TAG_subprogram +# CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +# CHECK-NOT: DW_TAG +# CHECK: DW_AT_specification {{.*}} "_ZN1C5m_fn3Ev" +# CHECK-NOT: DW_TAG +# Here should not be an inlined subroutine with 0 length. +# CHECK: NULL +# +# CHECK: Address Line Column File ISA Discriminator Flags +# CHECK-NEXT: --- +# CHECK-NEXT: 25 0 1 0 0 is_stmt +# CHECK-NEXT: 29 28 1 0 0 is_stmt prologue_end +# CHECK-NEXT: 29 28 1 0 0 is_stmt end_sequence +--- | + source_filename = "t.ll" + target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + target triple = "x86_64-apple-macosx" + + %class.E = type { %class.D } + %class.D = type { %class.B } + %class.B = type { %class.A, %class.A } + %class.A = type { i8 } + %class.C = type <{ %class.E*, %class.B, [2 x i8] }> + + @a = local_unnamed_addr global %class.E* null, align 4 + + define i32 @_ZN1C5m_fn3Ev(%class.C* nocapture) local_unnamed_addr align 2 !dbg !6 { + %2 = alloca %class.B, align 1 + %3 = load %class.E*, %class.E** @a, align 4 + %4 = icmp eq %class.E* %3, null + br i1 %4, label %10, label %5 + + ;