authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-25 14:20:15-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-25 14:20:15-04:00
logefa771af754281cd76a77ef22af107eb0a9aaf9a
treecbc8a86a19b928f1b11755930619fc7de8a1ada1
parente0050af293146a38e2122413196e66f73d90f2e0

compile time improvement - add __zig_panic_slice fn

move some boilerplate code having to do with panicking to a function. Here's the timing difference. It's not much: Before: full test: 1m36.511s debug test: 20.862s hello.zig Name Start End Duration Percent Initialize 0.0000 0.0000 0.0000 0.0001 Semantic Analysis 0.0000 0.0421 0.0420 0.2109 Code Generation 0.0421 0.0620 0.0200 0.1003 LLVM Emit Object 0.0620 0.1852 0.1231 0.6180 Build Dependencies 0.1852 0.1974 0.0122 0.0615 LLVM Link 0.1974 0.1993 0.0018 0.0093 Generate .h 0.1993 0.1993 0.0000 0.0000 Total 0.0000 0.1993 0.1993 1.0000 After: full test: 1m33.588s debug test: 20.303s hello.zig Name Start End Duration Percent Initialize 0.0000 0.0000 0.0000 0.0002 Semantic Analysis 0.0000 0.0425 0.0425 0.2202 Code Generation 0.0425 0.0675 0.0250 0.1293 LLVM Emit Object 0.0675 0.1789 0.1114 0.5773 Build Dependencies 0.1789 0.1913 0.0124 0.0640 LLVM Link 0.1913 0.1931 0.0018 0.0091 Generate .h 0.1931 0.1931 0.0000 0.0000 Total 0.0000 0.1931 0.1931 1.0000

2 files changed, 33 insertions(+), 1 deletions(-)

src/all_types.hpp+1
...@@ -1460,6 +1460,7 @@ struct CodeGen {...@@ -1460,6 +1460,7 @@ struct CodeGen {
1460 LLVMValueRef err_name_table;1460 LLVMValueRef err_name_table;
1461 size_t largest_err_name_len;1461 size_t largest_err_name_len;
1462 LLVMValueRef safety_crash_err_fn;1462 LLVMValueRef safety_crash_err_fn;
1463 LLVMValueRef panic_slice_fn;
14631464
1464 IrInstruction *invalid_instruction;1465 IrInstruction *invalid_instruction;
1465 ConstExprValue const_void_val;1466 ConstExprValue const_void_val;
src/codegen.cpp+32-1
...@@ -647,8 +647,28 @@ static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len...@@ -647,8 +647,28 @@ static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len
647 LLVMBuildUnreachable(g->builder);647 LLVMBuildUnreachable(g->builder);
648}648}
649649
650static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {650static LLVMValueRef get_panic_slice_fn(CodeGen *g) {
651 if (g->panic_slice_fn != nullptr)
652 return g->panic_slice_fn;
653
651 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);654 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
655 TypeTableEntry *ptr_to_str_type = get_pointer_to_type(g, str_type, true);
656
657 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_panic_slice"), false);
658 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), &ptr_to_str_type->type_ref, 1, false);
659 LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
660 addLLVMFnAttr(fn_val, "noreturn");
661 addLLVMFnAttr(fn_val, "cold");
662 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
663 LLVMSetFunctionCallConv(fn_val, LLVMFastCallConv);
664
665 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
666 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
667 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder);
668 LLVMPositionBuilderAtEnd(g->builder, entry_block);
669
670 LLVMValueRef msg_arg = LLVMGetParam(fn_val, 0);
671
652 size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index;672 size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index;
653 size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index;673 size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index;
654 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, (unsigned)ptr_index, "");674 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, (unsigned)ptr_index, "");
...@@ -657,6 +677,17 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {...@@ -657,6 +677,17 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {
657 LLVMValueRef msg_ptr = LLVMBuildLoad(g->builder, ptr_ptr, "");677 LLVMValueRef msg_ptr = LLVMBuildLoad(g->builder, ptr_ptr, "");
658 LLVMValueRef msg_len = LLVMBuildLoad(g->builder, len_ptr, "");678 LLVMValueRef msg_len = LLVMBuildLoad(g->builder, len_ptr, "");
659 gen_panic_raw(g, msg_ptr, msg_len);679 gen_panic_raw(g, msg_ptr, msg_len);
680
681 LLVMPositionBuilderAtEnd(g->builder, prev_block);
682 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
683 g->panic_slice_fn = fn_val;
684 return g->panic_slice_fn;
685}
686
687static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {
688 LLVMValueRef fn_val = get_panic_slice_fn(g);
689 LLVMBuildCall(g->builder, fn_val, &msg_arg, 1, "");
690 LLVMBuildUnreachable(g->builder);
660}691}
661692
662static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {693static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {