Reposting in Phabricator as requested.
Currently, LLVM cannot represent locations for aggregate variables that
are fragmented across multiple Values. This situation arises, e.g.,
during SROA, or even as part of the x86_64 calling convention when a struct
is passed by value. This patch adds the functionality to emit
DWARF location expressions using DW_OP(_bit)_piece to express partial
values.
This is implemented by adding a new operation type OpPiece to complex
DIVariables which accepts an offset and a size.
The canonical example would be something like this:
typedef struct { long int a; int b;} S; int foo(S s) { return s.b; }
which at -O1 is now codegen’d into:
; Function Attrs: nounwind readnone ssp uwtable define i32 @foo(i64 %s.coerce0, i32 %s.coerce1) #0 { entry: tail call void @llvm.dbg.value(metadata !{i64 %s.coerce0}, i64 0, metadata !20) tail call void @llvm.dbg.value(metadata !{i32 %s.coerce1}, i64 0, metadata !21) ret i32 %s.coerce1, !dbg !24 }
with this patch we'd emit the following DWARF:
0x00000047: TAG_formal_parameter [3] AT_name( "s" ) AT_decl_file( "struct.c" ) AT_decl_line( 3 ) AT_type( {0x00000069} ( S ) ) AT_location( 0x00000000 0x0000000000000000 - 0x0000000000000008: rdi, piece 0x00000008 0x0000000000000000 - 0x0000000000000006: rsi, bit-piece 32 64 0x0000000000000006 - 0x0000000000000008: rax, bit-piece 32 64 )
cheers,
adrian
Remove commented out code (& unrelated whitespace changes) - then this file shouldn't be included in the diff at all.
Ideally this whole change shouldn't have any changes to core debug info APIs/IR APIs - those changes have already been committed. This change is now just about teaching certain optimizations to preserve/create the IR necessary to describe the variable location fragments, right?