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
These are of Value *s, but what Values? The loads? The allocas? Something else?
Essentially, I think this comment needs to indicate what the synthetic "use" edge looks like for the purpose of SROA.