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: unassignedb...@nondot.org Reporter: r...@google.com CC: llvm-bugs@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.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs