<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - .cv_loc and .cv_inline_linetable directives do not represent source locations of nested inlined call sites"
   href="https://llvm.org/bugs/show_bug.cgi?id=29146">29146</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>.cv_loc and .cv_inline_linetable directives do not represent source locations of nested inlined call sites
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>MC
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>rnk@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>