[llvm-bugs] [Bug 29146] New: .cv_loc and .cv_inline_linetable directives do not represent source locations of nested inlined call sites

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Aug 25 17:40:26 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=29146

            Bug ID: 29146
           Summary: .cv_loc and .cv_inline_linetable directives do not
                    represent source locations of nested inlined call
                    sites
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: MC
          Assignee: unassignedbugs at nondot.org
          Reporter: rnk at google.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

This is problematic when you have inlined wrapper functions that don't have any
instructions attributed to them. Consider this example C code:

volatile int x;
__forceinline void foo() { ++x; }
__forceinline void bar() { foo(); }
void baz() { bar(); }

$ clang -S t.c  -o - -gcodeview -gline-tables-only -O1 | grep \.cv_
        .cv_file        1 "C:\\src\\llvm\\build\\t.c"
        .cv_loc 0 1 4 0 is_stmt 0       # t.c:4:0
        .cv_loc 1 1 2 28                # t.c:2:28
        .cv_loc 0 1 6 3                 # t.c:6:3
        .cv_inline_linetable    2 1 3 .Lfunc_begin0 .Lfunc_end0 contains 1
        .cv_inline_linetable    1 1 2 .Lfunc_begin0 .Lfunc_end0
        .cv_linetable   0, main, .Lfunc_end0
        .cv_filechecksums               # File index to string table offset
subsection
        .cv_stringtable                 # String table

These directives do not describe the call from 'bar' to 'foo' on line 3 at all.
When we emit the binary annotations for the call site of 'bar', they are empty,
so windbg appears to ignore them.

There are two ways we can handle this, but they come with tradeoffs.

1. When processing a DILocation, we could emit a .cv_loc directive for every
inline site in its stack of inlinedAt locations. In this example, we would get:

        .cv_loc 0 1 4 0 is_stmt 0       # t.c:4:0  // prologue of baz
        .cv_loc 2 1 3 28                # t.c:3:28 // note the callsite of foo
in bar
        .cv_loc 1 1 2 28                # t.c:2:28 // the volatile inc in foo
        .cv_loc 0 1 6 3                 # t.c:6:3  // the return in baz


It could easily get messy when the code gets reordered, though. Consider this
example:

volatile int x;
__forceinline void foo() {
  ++x;
  ++x;
}
__forceinline void bar() { foo(); }
int main() {
  bar();
  return 0;
}

If the "xor %eax, %eax" instruction is attributed to the 'return' line and is
rescheduled between the volatile 'inc' instructions, then our directives look
like:

        .seh_endprologue
        .cv_loc 2 1 3 3                 # t.c:6:3
        .cv_loc 1 1 3 3                 # t.c:3:3
        incl    x(%rip)
        .cv_loc 0 1 9 3                 # t.c:9:3
        xorl    %eax, %eax
        .cv_loc 2 1 3 3                 # t.c:6:3
        .cv_loc 1 1 4 3                 # t.c:4:3
        incl    x(%rip)
        .cv_loc 0 1 9 3                 # t.c:9:3
        retq

And if I keep adding wrappers like 'bar' (think STL), every scheduling decision
could create a large number of .cv_loc directives, each of which has its own
internal MCSymbol temporary label. That makes me feel like keeping things more
normalized is better. On to idea #2...


2. Extend the "contains" list to include "inlinedAt" information. Working with
the same example, we'd change the .cv_inline_linetable directive to look like
this in my first example:
        .cv_inline_linetable   2 declared_at 1 3 inlined_at 1 4 .Lfunc_begin0
.Lfunc_end0 contains 1
        .cv_inline_linetable   1 declared_at 1 2 inlined_at 1 3 .Lfunc_begin0
.Lfunc_end0

This re-normalizes the DILocation inlinedAt info somewhat, reduces the asm
verbosity, and eliminates redundant labels. If we renormalize this, then maybe
we should go and renormalize the "contains" list complete, though. When we
designed it, the idea was that assemblers should be "dumb", and we should do as
much simplification as possible in the compiler, rather than requiring multiple
assembler passes.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160826/b14098cc/attachment.html>


More information about the llvm-bugs mailing list