Skip to content

Commit fe4f635

Browse files
committed
Revise prologue-end setting as per Davids feedback
1 parent 30a0c4e commit fe4f635

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,6 +2218,7 @@ findPrologueEndLoc(const MachineFunction *MF) {
22182218
const auto &TII = *MF->getSubtarget().getInstrInfo();
22192219
const MachineInstr *NonTrivialInst = nullptr;
22202220
const Function &F = MF->getFunction();
2221+
DISubprogram *SP = const_cast<DISubprogram*>(F.getSubprogram());
22212222

22222223
// Some instructions may be inserted into prologue after this function. Must
22232224
// keep prologue for these cases.
@@ -2305,15 +2306,36 @@ findPrologueEndLoc(const MachineFunction *MF) {
23052306
return *FoundInst;
23062307
}
23072308

2308-
// We choose to ignore line-zero locations when setting the prologue as they
2309-
// can't be stepped on anyway; however in very rare scenarios function calls
2310-
// can have line zero, and we shouldn't step over those. In these
2311-
// extraordinary conditions, just bail out and refuse to set a prologue_end.
2312-
if (CurInst->isCall())
2313-
if (const DILocation *Loc = CurInst->getDebugLoc().get())
2314-
if (Loc->getLine() == 0)
2309+
// In very rare scenarios function calls can have line zero, and we
2310+
// shouldn't step over such a call while trying to reach prologue_end. In
2311+
// these extraordinary conditions, force an earlier setup instruction to
2312+
// have the scope line and put prologue_end there. This will be suboptimal,
2313+
// and might still be in setup code, but is less catastrophic than missing
2314+
// a call.
2315+
if (CurInst->isCall()) {
2316+
if (const DILocation *Loc = CurInst->getDebugLoc().get();
2317+
Loc && Loc->getLine() == 0) {
2318+
// Go back one instruction.
2319+
auto RIt = std::next(CurInst->getIterator().getReverse());
2320+
// In the radically unlikely event that there's no prior instruction,
2321+
// meaning the first instruction in the function is a call, don't set a
2322+
// prologue_end at all.
2323+
if (RIt == CurInst->getParent()->rend())
23152324
return std::make_pair(nullptr, true);
23162325

2326+
// The prior instruction was either line-zero or unset, or a setup
2327+
// instruction, or otherwise uninteresting. Force it to have the
2328+
// scope line.
2329+
unsigned ScopeLine = SP->getScopeLine();
2330+
DILocation *ScopeLineDILoc =
2331+
DILocation::get(SP->getContext(), ScopeLine, 0, SP);
2332+
const_cast<MachineInstr*>(&*RIt)->setDebugLoc(ScopeLineDILoc);
2333+
2334+
// Consider this position to be where prologue_end is placed.
2335+
return std::make_pair(&*RIt, false);
2336+
}
2337+
}
2338+
23172339
// Try to continue searching, but use a backup-location if substantive
23182340
// computation is happening.
23192341
auto NextInst = std::next(CurInst);

llvm/test/DebugInfo/X86/no-prologue-end-after-line0-calls.mir

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# RUN: llc %s -start-after=livedebugvalues -o - -filetype=obj | llvm-dwarfdump - --debug-line | FileCheck %s --implicit-check-not=prologue_end
1+
# RUN: llc %s -start-after=livedebugvalues -o - -filetype=obj | llvm-dwarfdump - --debug-line | FileCheck %s
22
#
33
## Original code, compiled clang -O2 -g -c
44
##
@@ -23,25 +23,25 @@
2323
## a: 59 pop %rcx
2424
## b: c3 ret
2525
##
26-
## Where prologue_end is placed on address 8, the clearing of the return
27-
## register, because it's the first "real" instruction that isn't line zero.
28-
## This then causes debuggers to skip over the call instruction when entering
29-
## the function, which is catastrophic.
26+
## And we could choose to set prologue_end on address 8, the clearing of the
27+
## return register, because it's the first "real" instruction that isn't line
28+
## zero. But this then causes debuggers to skip over the call instruction when
29+
## entering the function, which is catastrophic.
3030
##
31-
## Instead: we shouldn't put a prologue_end on this function at all. It's too
32-
## deformed from the original code to truly have a position (with a line number)
33-
## that is both true, and after frame setup. This gives consumers the
31+
## Instead: we force the xor at address 1 to have a source location (the
32+
## function scope line number), and put a prologue_end there. While it's a
33+
## setup instruction, it's better to have a prologue_end that's still slightly
34+
## in the prologue than to step over the call. This gives consumers the
3435
## opportunity to recognise "this is a crazy function" and act accordingly.
3536
##
36-
## Check lines ensure that there's something meaningful in the line table
37-
## involving line 2, the implicit-check-not is making sure there isn't a
38-
## prologue_end flag on any line entry.
37+
## Check lines: the first entry is the start-of-function scope line, the second
38+
## entry is the prologue_end on the xor, while the third is the zero-line-number
39+
## call instruction.
3940
#
40-
# CHECK: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0
41-
#
42-
# CHECK: Address Line Column File
43-
# CHECK: 2 0 0
44-
# CHECK: end_sequence
41+
# CHECK: 2 0 0 0 0 0 is_stmt
42+
# CHECK-NEXT: 2 0 0 0 0 0 is_stmt prologue_end
43+
# CHECK-NEXT: 0 0 0 0 0 0
44+
4545
--- |
4646
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
4747
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)