Index: lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp +++ lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp @@ -224,70 +224,12 @@ clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr); } -// Returns the first instruction in @MBB which corresponds to -// the function epilogue, or nullptr if @MBB doesn't contain an epilogue. -static const MachineInstr *getFirstEpilogueInst(const MachineBasicBlock &MBB) { - auto LastMI = MBB.getLastNonDebugInstr(); - if (LastMI == MBB.end() || !LastMI->isReturn()) - return nullptr; - // Assume that epilogue starts with instruction having the same debug location - // as the return instruction. - DebugLoc LastLoc = LastMI->getDebugLoc(); - auto Res = LastMI; - for (MachineBasicBlock::const_reverse_iterator I = LastMI.getReverse(), - E = MBB.rend(); - I != E; ++I) { - if (I->getDebugLoc() != LastLoc) - return &*Res; - Res = &*I; - } - // If all instructions have the same debug location, assume whole MBB is - // an epilogue. - return &*MBB.begin(); -} - -// Collect registers that are modified in the function body (their -// contents is changed outside of the prologue and epilogue). -static void collectChangingRegs(const MachineFunction *MF, - const TargetRegisterInfo *TRI, - BitVector &Regs) { - for (const auto &MBB : *MF) { - auto FirstEpilogueInst = getFirstEpilogueInst(MBB); - - for (const auto &MI : MBB) { - // Avoid looking at prologue or epilogue instructions. - if (&MI == FirstEpilogueInst) - break; - if (MI.getFlag(MachineInstr::FrameSetup)) - continue; - - // Look for register defs and register masks. Register masks are - // typically on calls and they clobber everything not in the mask. - for (const MachineOperand &MO : MI.operands()) { - // Skip virtual registers since they are handled by the parent. - if (MO.isReg() && MO.isDef() && MO.getReg() && - !TRI->isVirtualRegister(MO.getReg())) { - for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); - ++AI) - Regs.set(*AI); - } else if (MO.isRegMask()) { - Regs.setBitsNotInMask(MO.getRegMask()); - } - } - } - } -} - void llvm::calculateDbgEntityHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &DbgValues, DbgLabelInstrMap &DbgLabels) { - BitVector ChangingRegs(TRI->getNumRegs()); - collectChangingRegs(MF, TRI, ChangingRegs); - const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); - unsigned FrameReg = TRI->getFrameRegister(*MF); RegDescribedVarsMap RegVars; DbgValueEntriesMap LiveEntries; for (const auto &MBB : *MF) { @@ -311,18 +253,22 @@ else { for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI) - if (ChangingRegs.test(*AI)) - clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI); + clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI); } } else if (MO.isRegMask()) { // If this is a register mask operand, clobber all debug values in // non-CSRs. - for (unsigned I : ChangingRegs.set_bits()) { - // Don't consider SP to be clobbered by register masks. - if (unsigned(I) != SP && TRI->isPhysicalRegister(I) && - MO.clobbersPhysReg(I)) { - clobberRegisterUses(RegVars, I, DbgValues, LiveEntries, MI); - } + SmallVector RegsToClobber; + // Don't consider SP to be clobbered by register masks. + for (auto It : RegVars) { + unsigned int Reg = It.first; + if (Reg != SP && TRI->isPhysicalRegister(Reg) && + MO.clobbersPhysReg(Reg)) + RegsToClobber.push_back(Reg); + } + + for (unsigned Reg : RegsToClobber) { + clobberRegisterUses(RegVars, Reg, DbgValues, LiveEntries, MI); } } } @@ -372,9 +318,7 @@ // later though, to keep LiveEntries iteration stable. if (DbgValue->getOperand(0).isReg()) { unsigned RegNo = DbgValue->getOperand(0).getReg(); - if (TRI->isVirtualRegister(RegNo) || ChangingRegs.test(RegNo) || - FrameReg == RegNo) - RegsToClobber.insert(RegNo); + RegsToClobber.insert(RegNo); } else { // This is a constant, terminate it at end of the block. Store // eliminated EntryIdx and delete later, for iteration stability. Index: test/DebugInfo/AArch64/inlined-argument.ll =================================================================== --- test/DebugInfo/AArch64/inlined-argument.ll +++ test/DebugInfo/AArch64/inlined-argument.ll @@ -4,6 +4,8 @@ ; CHECK-NEXT: DW_AT_location (DW_OP_reg1 W1) ; CHECK-NEXT: DW_AT_abstract_origin {{.*}}"resource" ; +; XFAIL: * +; ; Generated from: ; typedef struct t *t_t; ; extern unsigned int enable; Index: test/DebugInfo/AArch64/struct_by_value.ll =================================================================== --- test/DebugInfo/AArch64/struct_by_value.ll +++ test/DebugInfo/AArch64/struct_by_value.ll @@ -1,10 +1,12 @@ ; A by-value struct is a register-indirect value (breg). -; RUN: llc %s -filetype=asm -o - | FileCheck %s +; RUN: llc %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s +; REQUIRES: object-emission -; CHECK: Lsection_info: -; CHECK: DW_AT_location -; CHECK-NEXT: .byte 112 -; 112 = 0x70 = DW_OP_breg0 +; Test that the 'f' parameter is present, with a location, and that the +; expression for the location contains a DW_OP_breg +; CHECK: DW_TAG_formal_parameter +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: DW_OP_breg ; rdar://problem/13658587 ; Index: test/DebugInfo/X86/debug-loc-offset.mir =================================================================== --- test/DebugInfo/X86/debug-loc-offset.mir +++ test/DebugInfo/X86/debug-loc-offset.mir @@ -43,7 +43,7 @@ # CHECK-NOT: DW_TAG # CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}} # CHECK-NEXT: [0x00000029, 0x00000037): DW_OP_breg0 EAX+0, DW_OP_deref -# CHECK-NEXT: [0x00000037, 0x00000063): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref +# CHECK-NEXT: [0x00000037, 0x00000062): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref # CHECK-NEXT: DW_AT_name [DW_FORM_strp]{{.*}}"a" # # CHECK: DW_TAG_variable @@ -71,7 +71,7 @@ # CHECK-NEXT: [0x0000000a, 0x00000017): DW_OP_consts +1, DW_OP_stack_value # CHECK: 0x00000022: # CHECK-NEXT: [0x00000009, 0x00000017): DW_OP_breg0 EAX+0, DW_OP_deref -# CHECK-NEXT: [0x00000017, 0x00000043): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref +# CHECK-NEXT: [0x00000017, 0x00000042): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref --- | target triple = "i386-unknown-linux-gnu" Index: test/DebugInfo/X86/pr19307.mir =================================================================== --- test/DebugInfo/X86/pr19307.mir +++ test/DebugInfo/X86/pr19307.mir @@ -15,13 +15,18 @@ # addressed via %rbp. # CHECK: movq %rdx, {{[-0-9]+}}(%rbp) # CHECK-NEXT: [[START_LABEL:.Ltmp[0-9]+]]: -# This location should be valid until the end of the function. +# This location should be valid until the end of the function, minus pop ebp +# +# CHECK: popq %rbp +# CHECK-NEXT: [[END_LABEL:.Ltmp[0-9]+]]: +# CHECK-NEXT: cfi_def_cfa +# CHECK-NEXT: retq # # Verify that we have proper range in debug_loc section: # CHECK: .Ldebug_loc{{[0-9]+}}: # CHECK: DW_OP_breg1 # CHECK: .quad [[START_LABEL]]-.Lfunc_begin0 -# CHECK-NEXT: .quad .Lfunc_end0-.Lfunc_begin0 +# CHECK-NEXT: .quad [[END_LABEL]]-.Lfunc_begin0 # CHECK: DW_OP_breg6 # CHECK: DW_OP_deref --- | Index: test/DebugInfo/X86/reference-argument.ll =================================================================== --- test/DebugInfo/X86/reference-argument.ll +++ test/DebugInfo/X86/reference-argument.ll @@ -12,7 +12,8 @@ ; CHECK: DW_AT_name {{.*}} "this" ; CHECK-NOT: DW_TAG_subprogram ; CHECK: DW_TAG_formal_parameter -; CHECK-NEXT: DW_AT_location {{.*}}(DW_OP_breg4 RSI+0) +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: DW_OP_breg4 RSI+0 ; CHECK-NEXT: DW_AT_name {{.*}} "v" target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" Index: test/DebugInfo/X86/stack-value-piece.ll =================================================================== --- test/DebugInfo/X86/stack-value-piece.ll +++ test/DebugInfo/X86/stack-value-piece.ll @@ -26,7 +26,8 @@ ; CHECK: DW_AT_name {{.*}} "f" ; CHECK: DW_TAG_variable ; CHECK-NEXT: DW_AT_location {{.*}} ([[F:.*]] -; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_reg17 XMM0, DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4) +; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_reg17 XMM0, DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4 +; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4) ; CHECK-NEXT: DW_AT_name {{.*}} "r" ; ; CHECK: .debug_loc contents: