(Based on D16569 by friss; that revision was 'abandoned' so I needed to
create a new one. The following description is derived from his.)
There will always be instructions with no line information attached.
One example is the LocalValue constants generated by FastISel, but
it's by far not the only one. Compiler generated code will have no
line info and might get inlined. SelectionDAG is full of nodes that
won't have any line information (because they could be shared).
Multiple attempts have been made over time to fix the FastISel issue,
but none have felt satisfactory enough to be committed. As the problem
is much more general than just FastISel, this patch addresses it
at line table emission time rather than instruction selection time.
It also doesn't try to give accurate line information for these
instructions, but rather marks them with a 'no line' indicator so that
the debugger can safely ignore them.
The implemented heuristic will add 'no line' information to every insn
without explicit line information and either:
- at the beginning of a basic-block
- first instruction after a label
The first condition handles the FastISel case, while the second
enforces that any instruction referenced by anything (including debug
info) has line information.
The patch handles both DWARF and Codeview, using line number 0 for
DWARF and the reserved 'NeverStepIntoLineNumber' value for Codeview.
(I know almost nothing about Codeview so that might not be best...)
The initial measurements on DWARF line table size show an impact
between 5% and 15% (the latter is for a control-flow heavy code
eg. ASANified).
There was already an option to use DWARF 'line 0' information for all
the instructions with no debug locations. The commit history for this
code show that it was disabled because it caused issues with GDB and
with the line table size. Note that this code was unconditionally
emitting the line 0 information and not using a heuristic to find
interesting instructions like this one.
This patch has been tested on GDB-7.8 and current LLDB (pretty
sure I got the LLDB part right, but it's hard to tell). GDB showed no
differences, and LLDB had one XPASS (but I am not sure that isn't
just a fluke, as it was 'test_process_interrupt_dwarf' and I've had
flakiness problems with GDB thread-related tests in the past).
I don't know how to test the Codeview side.
If you initialize this here to nullptr, you don't have to change the constructor.