diff --git a/src/compiler/llvm_codegen_builtins.c b/src/compiler/llvm_codegen_builtins.c index ade002504..614ecbe2e 100644 --- a/src/compiler/llvm_codegen_builtins.c +++ b/src/compiler/llvm_codegen_builtins.c @@ -132,7 +132,7 @@ INLINE void llvm_emit_stacktrace(GenContext *c, BEValue *result_value, Expr *exp llvm_value_set(result_value, llvm_get_zero(c, type_voidptr), type_voidptr); return; } - llvm_value_set(result_value, c->debug.stacktrace, type_voidptr); + llvm_value_set(result_value, c->debug.stacktrace.ref, type_voidptr); } INLINE void llvm_emit_volatile_store(GenContext *c, BEValue *result_value, Expr *expr) diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index c10c188f7..847e64fb9 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -29,7 +29,7 @@ static inline void llvm_emit_initializer_list_expr(GenContext *c, BEValue *value static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr *expr); static inline void llvm_emit_post_inc_dec(GenContext *c, BEValue *value, Expr *expr, int diff); static inline void llvm_emit_pre_inc_dec(GenContext *c, BEValue *value, Expr *expr, int diff); -static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type *type, AstId current, BlockExit **block_exit, LLVMValueRef *old_stack_trace); +static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type *type, AstId current, BlockExit **block_exit, Stacktrace *old_stack_trace); static inline void llvm_emit_subscript_addr_with_base(GenContext *c, BEValue *result, BEValue *parent, BEValue *index, SourceSpan loc); static inline void llvm_emit_try_unwrap(GenContext *c, BEValue *value, Expr *expr); static inline void llvm_emit_any(GenContext *c, BEValue *value, Expr *expr); @@ -5799,7 +5799,7 @@ static inline void llvm_emit_expression_list_expr(GenContext *c, BEValue *be_val } } -static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type *type, AstId current, BlockExit **block_exit, LLVMValueRef *old_stack_trace) +static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type *type, AstId current, BlockExit **block_exit, Stacktrace *old_stack_trace) { Type *type_lowered = type_lowering(type); @@ -5994,7 +5994,7 @@ static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr FOREACH_END(); bool restore_at_exit = false; - LLVMValueRef old_stack_trace; + Stacktrace old_stack_trace; if (llvm_use_debug(c)) { llvm_debug_push_lexical_scope(c, astptr(expr->macro_block.first_stmt)->span); @@ -6003,7 +6003,6 @@ static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr restore_at_exit = true; llvm_emit_update_stack_row(c, expr->span.row); Decl *macro = expr->macro_block.macro; - Module *macro_module = macro->unit->module; old_stack_trace = c->debug.stacktrace; llvm_emit_push_stacktrace(c, macro, macro->name, ST_MACRO); } diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index 3f0ed6796..18b94a7bd 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -464,20 +464,22 @@ static void llvm_emit_stacktrace_definitions(GenContext *c) c->builder = NULL; } -void llvm_emit_pop_stacktrace(GenContext *c, LLVMValueRef *slot) +void llvm_emit_pop_stacktrace(GenContext *c, Stacktrace *slot) { if (!c->debug.enable_stacktrace) return; if (slot) { c->debug.stacktrace = *slot; } - llvm_store_to_ptr_raw_aligned(c, c->debug.current_stack_ptr, c->debug.stacktrace, type_alloca_alignment(type_voidptr)); + llvm_store_to_ptr_raw_aligned(c, c->debug.current_stack_ptr, c->debug.stacktrace.ref, type_alloca_alignment(type_voidptr)); } void llvm_emit_update_stack_row(GenContext *c, uint32_t row) { if (!c->debug.enable_stacktrace) return; - LLVMValueRef row_ptr = LLVMBuildStructGEP2(c->builder, c->debug.stack_type, c->debug.stacktrace, 4, ".$row"); - llvm_store_to_ptr_raw_aligned(c, row_ptr, llvm_const_int(c, type_uint, row ? row : 1), type_abi_alignment(type_uint)); + if (row == 0) row = 1; + if (c->debug.stacktrace.last_row == row) return; + c->debug.stacktrace.last_row = row; + llvm_store_to_ptr_raw_aligned(c, c->debug.stacktrace.row, llvm_const_int(c, type_uint, row), type_abi_alignment(type_uint)); } void llvm_emit_push_stacktrace(GenContext *c, Decl *decl, const char *function_name, StacktraceType type) @@ -498,21 +500,21 @@ void llvm_emit_push_stacktrace(GenContext *c, Decl *decl, const char *function_n file_name, llvm_const_int(c, type_usz, file_name_len), llvm_const_int(c, type_uint, type), llvm_const_int(c, type_uint, decl->span.row)}; - LLVMBuildCall2(c->builder, c->debug.stack_init_fn_type, c->debug.stack_init_fn, args, 7, ""); - + LLVMValueRef call = LLVMBuildCall2(c->builder, c->debug.stack_init_fn_type, c->debug.stack_init_fn, args, 7, ""); + llvm_attribute_add_call(c, call, attribute_id.alwaysinline, -1, 0); if (type == ST_FUNCTION && (function_name == kw_main || function_name == kw_mainstub)) { AlignSize align_size; LLVMValueRef last = llvm_emit_struct_gep_raw(c, stacktrace, slot_type, 0, alignment, &align_size); llvm_store_to_ptr_raw_aligned(c, last, LLVMConstNull(c->ptr_type), align_size); } - c->debug.stacktrace = stacktrace; + LLVMValueRef row_ptr = LLVMBuildStructGEP2(c->builder, c->debug.stack_type, stacktrace, 4, ".$row"); + c->debug.stacktrace = (Stacktrace) { .row = row_ptr, .ref = stacktrace, .last_row = ~(uint32_t)0 }; } -void -llvm_emit_body(GenContext *c, LLVMValueRef function, FunctionPrototype *prototype, Signature *signature, Ast *body, - Decl *decl, StacktraceType type) +void llvm_emit_body(GenContext *c, LLVMValueRef function, FunctionPrototype *prototype, + Signature *signature, Ast *body, Decl *decl, StacktraceType type) { bool emit_debug = llvm_use_debug(c); LLVMValueRef prev_function = c->function; diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 7cbea36e1..6b08e9b69 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -61,6 +61,13 @@ typedef enum ST_FINALIZER } StacktraceType; +typedef struct +{ + uint32_t last_row; + LLVMValueRef row; + LLVMValueRef ref; +} Stacktrace; + typedef struct { unsigned runtime_version : 8; @@ -77,7 +84,7 @@ typedef struct LLVMValueRef stack_init_fn; LLVMTypeRef stack_init_fn_type; LLVMTypeRef stack_type; - LLVMValueRef stacktrace; + Stacktrace stacktrace; } DebugContext; @@ -521,9 +528,8 @@ void llvm_emit_debug_parameter(GenContext *c, Decl *parameter, unsigned index); void llvm_emit_debug_local_var(GenContext *c, Decl *var); void llvm_emit_debug_global_var(GenContext *c, Decl *global); void llvm_emit_update_stack_row(GenContext *c, uint32_t row); -void llvm_emit_pop_stacktrace(GenContext *c, LLVMValueRef *slot); -void -llvm_emit_push_stacktrace(GenContext *c, Decl *decl, const char *function_name, StacktraceType type); +void llvm_emit_pop_stacktrace(GenContext *c, Stacktrace *slot); +void llvm_emit_push_stacktrace(GenContext *c, Decl *decl, const char *function_name, StacktraceType type); #define EMIT_LOC(c, x) do { if (c->debug.builder) llvm_emit_debug_location(c, x->span); } while (0); diff --git a/src/version.h b/src/version.h index f4e18107c..eab88daaf 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.610" \ No newline at end of file +#define COMPILER_VERSION "0.4.611" \ No newline at end of file