Skip to content

Commit

Permalink
Improve callstack debug information #1184.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Apr 26, 2024
1 parent d80a33e commit 37f035e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 52 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- `assert(false)` only allowed in unused branches or in tests. Compile time failed asserts is a compile time error.
- Require expression blocks returning values to have the value used.
- Detect "unsigned >= 0" as errors.
- Improve callstack debug information #1184.

### Fixes
- Fixed issue in safe mode when converting enums.
Expand Down
8 changes: 2 additions & 6 deletions src/compiler/llvm_codegen_debug_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@ void llvm_emit_debug_location(GenContext *c, SourceSpan location)
LLVMMetadataRef loc = LLVMDIBuilderCreateDebugLocation(c->context,
row ? row : 1,
col ? col : 1,
scope, /* inlined at */ 0);

scope, c->inline_location);
LLVMSetCurrentDebugLocation2(c->builder, loc);
}

Expand Down Expand Up @@ -268,10 +267,7 @@ void llvm_debug_push_lexical_scope(GenContext *context, SourceSpan location)
{
debug_file = llvm_get_debug_file(context, location.file_id);
}
LLVMMetadataRef block =
LLVMDIBuilderCreateLexicalBlock(context->debug.builder, scope, debug_file,
row ? row : 1,
col ? col : 1);
LLVMMetadataRef block = LLVMDIBuilderCreateLexicalBlock(context->debug.builder, scope, debug_file, row ? row : 1, col ? col : 1);

llvm_debug_scope_push(context, block);
}
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -6151,6 +6151,15 @@ static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type

static inline void llvm_emit_expr_block(GenContext *c, BEValue *be_value, Expr *expr)
{
LLVMMetadataRef old_loc = c->inline_location;
if (!expr->expr_block.is_block)
{
SourceSpan span = expr->span;
LLVMMetadataRef loc = LLVMDIBuilderCreateDebugLocation(c->context, span.row, span.col,
llvm_debug_current_scope(c), old_loc);

c->inline_location = loc;
}
DEBUG_PUSH_LEXICAL_SCOPE(c, astptr(expr->expr_block.first_stmt)->span);
llvm_emit_return_block(c, be_value, expr->type, expr->expr_block.first_stmt, expr->expr_block.block_exit);
bool is_unreachable = expr->expr_block.is_noreturn && c->current_block;
Expand All @@ -6159,6 +6168,7 @@ static inline void llvm_emit_expr_block(GenContext *c, BEValue *be_value, Expr *
llvm_emit_unreachable(c);
}
DEBUG_POP_LEXICAL_SCOPE(c);
c->inline_location = old_loc;
}

LLVMValueRef llvm_emit_call_intrinsic(GenContext *context, unsigned intrinsic, LLVMTypeRef *types, unsigned type_count,
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/llvm_codegen_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ typedef struct GenContext_
LLVMBasicBlockRef current_block;
// The panic blocks to emit at the end.
LLVMBasicBlockRef *panic_blocks;
// Inline location
LLVMMetadataRef inline_location;
};
int ast_alloca_addr_space;
DebugContext debug;
Expand Down
93 changes: 47 additions & 46 deletions test/test_suite/concurrency/atomic_load_store_debug.c3t
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ fn void main()
/* #expect: test.ll
%.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] }
%any = type { ptr, i64 }

@"$ct.test.Ghh" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 12, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8
@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8

; Function Attrs:
define void @test.main() #0 !dbg !6 {
entry:
Expand All @@ -40,27 +38,26 @@ entry:
call void @llvm.dbg.declare(metadata ptr %x, metadata !14, metadata !DIExpression()), !dbg !15
%0 = load atomic i32, ptr %a seq_cst, align 4, !dbg !16
store i32 %0, ptr %x, align 4, !dbg !16
call void @llvm.dbg.declare(metadata ptr %y, metadata !19, metadata !DIExpression()), !dbg !20
%1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !21
store i32 %1, ptr %y, align 4, !dbg !21
%2 = load i32, ptr %x, align 4, !dbg !23
%add = add i32 123, %2, !dbg !24
store atomic i32 %add, ptr %a seq_cst, align 4, !dbg !25
%3 = load i32, ptr %y, align 4, !dbg !27
%add1 = add i32 33, %3, !dbg !28
store atomic volatile i32 %add1, ptr %a monotonic, align 4, !dbg !29
%4 = insertvalue %any undef, ptr %a, 0, !dbg !31
%5 = insertvalue %any %4, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !31
store %any %5, ptr %varargslots, align 16, !dbg !31
%6 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !32
ret void, !dbg !32
call void @llvm.dbg.declare(metadata ptr %y, metadata !20, metadata !DIExpression()), !dbg !21
%1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !22
store i32 %1, ptr %y, align 4, !dbg !22
%2 = load i32, ptr %x, align 4, !dbg !25
%add = add i32 123, %2, !dbg !26
store atomic i32 %add, ptr %a seq_cst, align 4, !dbg !27
%3 = load i32, ptr %y, align 4, !dbg !30
%add1 = add i32 33, %3, !dbg !31
store atomic volatile i32 %add1, ptr %a monotonic, align 4, !dbg !32
%4 = insertvalue %any undef, ptr %a, 0, !dbg !35
%5 = insertvalue %any %4, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !35
store %any %5, ptr %varargslots, align 16, !dbg !35
%6 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !36
ret void, !dbg !36
}

; Function Attrs:
define i32 @main(i32 %0, ptr %1) #0 !dbg !33 {
define i32 @main(i32 %0, ptr %1) #0 !dbg !37 {
entry:
call void @test.main(), !dbg !39
ret i32 0, !dbg !42
call void @test.main(), !dbg !43
ret i32 0, !dbg !47
}

declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
Expand All @@ -72,7 +69,6 @@ declare i1 @llvm.expect.i1(i1, i1) #2

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.dbg.cu = !{!4}

!0 = !{i32 2, !"Dwarf Version", i32 4}
!1 = !{i32 2, !"Debug Info Version", i32 3}
!2 = !{i32 2, !"frame-pointer", i32 2}
Expand All @@ -91,28 +87,33 @@ declare i1 @llvm.expect.i1(i1, i1) #2
!15 = !DILocation(line: 13, column: 6, scope: !6)
!16 = !DILocation(line:
!17 = distinct !DILexicalBlock(scope: !6, file: !18,
!18 = !DIFile(filename: "mem.c3"
!19 = !DILocalVariable(name: "y", scope: !6, file: !5, line: 14, type: !11, align: 4)
!20 = !DILocation(line: 14, column: 6, scope: !6)
!21 = !DILocation(line:
!22 = distinct !DILexicalBlock(scope: !6, file: !18
!23 = !DILocation(line: 15, column: 25, scope: !6)
!24 = !DILocation(line: 15, column: 19, scope: !6)
!25 = !DILocation(line:
!26 = distinct !DILexicalBlock(scope: !6, file: !18, line:
!27 = !DILocation(line: 16, column: 24, scope: !6)
!28 = !DILocation(line: 16, column: 19, scope: !6)
!29 = !DILocation(line:
!30 = distinct !DILexicalBlock(scope: !6, file: !18, line:
!31 = !DILocation(line: 17, column: 20, scope: !6)
!32 = !DILocation(line: 17, column: 6, scope: !6)
!33 = distinct !DISubprogram(name: "_$main", linkageName: "main"
!34 = !DISubroutineType(types: !35)
!35 = !{!11, !11, !36}
!36 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !37, size: 64, align: 64, dwarfAddressSpace: 0)
!37 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !38, size: 64, align: 64, dwarfAddressSpace: 0)
!38 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
!39 = !DILocation(line: 18, column: 2, scope: !40)
!40 = distinct !DILexicalBlock(scope: !33, file: !41, line: 18, column: 2)
!41 = !DIFile(filename: "main_stub.c3"
!42 = !DILocation(line: 19, column: 9, scope: !40)
!18 = !DIFile(filename: "mem.c3",
!19 = !DILocation(line: 13, column: 10, scope: !6)
!20 = !DILocalVariable(name: "y", scope: !6, file: !5, line: 14, type: !11, align: 4)
!21 = !DILocation(line: 14, column: 6, scope: !6)
!22 = !DILocation(line: 197, column: 23, scope: !23, inlinedAt: !24)
!23 = distinct !DILexicalBlock(scope: !6, file: !18, line: 197, column: 9)
!24 = !DILocation(line: 14, column: 10, scope: !6)
!25 = !DILocation(line: 15, column: 25, scope: !6)
!26 = !DILocation(line: 15, column: 19, scope: !6)
!27 = !DILocation(line: 212, column: 20, scope: !28, inlinedAt: !29)
!28 = distinct !DILexicalBlock(scope: !6, file: !18, line: 212, column: 2)
!29 = !DILocation(line: 15, column: 2, scope: !6)
!30 = !DILocation(line: 16, column: 24, scope: !6)
!31 = !DILocation(line: 16, column: 19, scope: !6)
!32 = !DILocation(line: 212, column: 20, scope: !33, inlinedAt: !34)
!33 = distinct !DILexicalBlock(scope: !6, file: !18, line: 212, column: 2)
!34 = !DILocation(line: 16, column: 2, scope: !6)
!35 = !DILocation(line: 17, column: 20, scope: !6)
!36 = !DILocation(line: 17, column: 6, scope: !6)
!37 = distinct !DISubprogram(name: "_$main", linkageName: "main"
!38 = !DISubroutineType(types: !39)
!39 = !{!11, !11, !40}
!40 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !41, size: 64, align: 64, dwarfAddressSpace: 0)
!41 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !42, size: 64, align: 64, dwarfAddressSpace: 0)
!42 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
!43 = !DILocation(line: 18, column: 2, scope: !44, inlinedAt: !46)
!44 = distinct !DILexicalBlock(scope: !37, file: !45, line: 18, column: 2)
!45 = !DIFile(filename: "main_stub.c3"
!46 = !DILocation(line: 10, column: 9, scope: !37)
!47 = !DILocation(line: 19, column: 9, scope: !44, inlinedAt: !46)

0 comments on commit 37f035e

Please sign in to comment.