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 {
14601460 LLVMValueRef err_name_table;
14611461 size_t largest_err_name_len;
14621462 LLVMValueRef safety_crash_err_fn;
1463 LLVMValueRef panic_slice_fn;
14631464
14641465 IrInstruction *invalid_instruction;
14651466 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
647647 LLVMBuildUnreachable(g->builder);
648648}
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
651654 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
652672 size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index;
653673 size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index;
654674 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, (unsigned)ptr_index, "");
......@@ -657,6 +677,17 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {
657677 LLVMValueRef msg_ptr = LLVMBuildLoad(g->builder, ptr_ptr, "");
658678 LLVMValueRef msg_len = LLVMBuildLoad(g->builder, len_ptr, "");
659679 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);
660691}
661692
662693static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {