authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-25 13:13:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-25 13:13:07-04:00
log754f7809e38d5d44da9d63241af310e6c0bee730
tree97e0ed0be14155ef271d15ba17b852014941cb45
parent629aa10c5672926eb5f8494296f5d5492cc2833f

refactor - codegen llvm functions lazily


3 files changed, 91 insertions(+), 105 deletions(-)

src/all_types.hpp-2
...@@ -1242,8 +1242,6 @@ struct BuiltinFnEntry {...@@ -1242,8 +1242,6 @@ struct BuiltinFnEntry {
1242 BuiltinFnId id;1242 BuiltinFnId id;
1243 Buf name;1243 Buf name;
1244 size_t param_count;1244 size_t param_count;
1245 uint32_t ref_count;
1246 LLVMValueRef fn_val;
1247};1245};
12481246
1249enum PanicMsgId {1247enum PanicMsgId {
src/codegen.cpp+91-101
...@@ -757,6 +757,25 @@ static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {...@@ -757,6 +757,25 @@ static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {
757 gen_panic(g, get_panic_msg_ptr_val(g, msg_id));757 gen_panic(g, get_panic_msg_ptr_val(g, msg_id));
758}758}
759759
760static LLVMValueRef get_memcpy_fn_val(CodeGen *g) {
761 if (g->memcpy_fn_val)
762 return g->memcpy_fn_val;
763
764 LLVMTypeRef param_types[] = {
765 LLVMPointerType(LLVMInt8Type(), 0),
766 LLVMPointerType(LLVMInt8Type(), 0),
767 LLVMIntType(g->pointer_size_bytes * 8),
768 LLVMInt32Type(),
769 LLVMInt1Type(),
770 };
771 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 5, false);
772 Buf *name = buf_sprintf("llvm.memcpy.p0i8.p0i8.i%d", g->pointer_size_bytes * 8);
773 g->memcpy_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
774 assert(LLVMGetIntrinsicID(g->memcpy_fn_val));
775
776 return g->memcpy_fn_val;
777}
778
760static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {779static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
761 if (g->safety_crash_err_fn != nullptr)780 if (g->safety_crash_err_fn != nullptr)
762 return g->safety_crash_err_fn;781 return g->safety_crash_err_fn;
...@@ -840,7 +859,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -840,7 +859,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
840 LLVMConstNull(LLVMInt1Type()), // is volatile859 LLVMConstNull(LLVMInt1Type()), // is volatile
841 };860 };
842861
843 LLVMBuildCall(g->builder, g->memcpy_fn_val, params, 5, "");862 LLVMBuildCall(g->builder, get_memcpy_fn_val(g), params, 5, "");
844863
845 LLVMValueRef const_prefix_len = LLVMConstInt(LLVMTypeOf(err_name_len), strlen(unwrap_err_msg_text), false);864 LLVMValueRef const_prefix_len = LLVMConstInt(LLVMTypeOf(err_name_len), strlen(unwrap_err_msg_text), false);
846 LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, "");865 LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, "");
...@@ -1060,7 +1079,7 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef...@@ -1060,7 +1079,7 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef
1060 LLVMConstNull(LLVMInt1Type()), // is volatile1079 LLVMConstNull(LLVMInt1Type()), // is volatile
1061 };1080 };
10621081
1063 return LLVMBuildCall(g->builder, g->memcpy_fn_val, params, 5, "");1082 return LLVMBuildCall(g->builder, get_memcpy_fn_val(g), params, 5, "");
1064}1083}
10651084
1066static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type,1085static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type,
...@@ -1947,6 +1966,25 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI...@@ -1947,6 +1966,25 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI
1947 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");1966 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
1948}1967}
19491968
1969static LLVMValueRef get_memset_fn_val(CodeGen *g) {
1970 if (g->memset_fn_val)
1971 return g->memset_fn_val;
1972
1973 LLVMTypeRef param_types[] = {
1974 LLVMPointerType(LLVMInt8Type(), 0),
1975 LLVMInt8Type(),
1976 LLVMIntType(g->pointer_size_bytes * 8),
1977 LLVMInt32Type(),
1978 LLVMInt1Type(),
1979 };
1980 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 5, false);
1981 Buf *name = buf_sprintf("llvm.memset.p0i8.i%d", g->pointer_size_bytes * 8);
1982 g->memset_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
1983 assert(LLVMGetIntrinsicID(g->memset_fn_val));
1984
1985 return g->memset_fn_val;
1986}
1987
1950static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,1988static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
1951 IrInstructionDeclVar *decl_var_instruction)1989 IrInstructionDeclVar *decl_var_instruction)
1952{1990{
...@@ -1993,7 +2031,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -1993,7 +2031,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
1993 LLVMConstNull(LLVMInt1Type()), // is volatile2031 LLVMConstNull(LLVMInt1Type()), // is volatile
1994 };2032 };
19952033
1996 LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, "");2034 LLVMBuildCall(g->builder, get_memset_fn_val(g), params, 5, "");
1997 }2035 }
1998 }2036 }
19992037
...@@ -2654,7 +2692,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns...@@ -2654,7 +2692,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
2654 is_volatile,2692 is_volatile,
2655 };2693 };
26562694
2657 LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, "");2695 LLVMBuildCall(g->builder, get_memset_fn_val(g), params, 5, "");
2658 return nullptr;2696 return nullptr;
2659}2697}
26602698
...@@ -2685,7 +2723,7 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns...@@ -2685,7 +2723,7 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
2685 is_volatile,2723 is_volatile,
2686 };2724 };
26872725
2688 LLVMBuildCall(g->builder, g->memcpy_fn_val, params, 5, "");2726 LLVMBuildCall(g->builder, get_memcpy_fn_val(g), params, 5, "");
2689 return nullptr;2727 return nullptr;
2690}2728}
26912729
...@@ -2799,23 +2837,63 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -2799,23 +2837,63 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
2799 }2837 }
2800}2838}
28012839
2840static LLVMValueRef get_trap_fn_val(CodeGen *g) {
2841 if (g->trap_fn_val)
2842 return g->trap_fn_val;
2843
2844 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false);
2845 g->trap_fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type);
2846 assert(LLVMGetIntrinsicID(g->trap_fn_val));
2847
2848 return g->trap_fn_val;
2849}
2850
2851
2802static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutable *executable, IrInstructionBreakpoint *instruction) {2852static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutable *executable, IrInstructionBreakpoint *instruction) {
2803 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");2853 LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");
2804 return nullptr;2854 return nullptr;
2805}2855}
28062856
2857static LLVMValueRef get_return_address_fn_val(CodeGen *g) {
2858 if (g->return_address_fn_val)
2859 return g->return_address_fn_val;
2860
2861 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
2862
2863 LLVMTypeRef fn_type = LLVMFunctionType(return_type->type_ref,
2864 &g->builtin_types.entry_i32->type_ref, 1, false);
2865 g->return_address_fn_val = LLVMAddFunction(g->module, "llvm.returnaddress", fn_type);
2866 assert(LLVMGetIntrinsicID(g->return_address_fn_val));
2867
2868 return g->return_address_fn_val;
2869}
2870
2807static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutable *executable,2871static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutable *executable,
2808 IrInstructionReturnAddress *instruction)2872 IrInstructionReturnAddress *instruction)
2809{2873{
2810 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref);2874 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref);
2811 return LLVMBuildCall(g->builder, g->return_address_fn_val, &zero, 1, "");2875 return LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, "");
2876}
2877
2878static LLVMValueRef get_frame_address_fn_val(CodeGen *g) {
2879 if (g->frame_address_fn_val)
2880 return g->frame_address_fn_val;
2881
2882 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
2883
2884 LLVMTypeRef fn_type = LLVMFunctionType(return_type->type_ref,
2885 &g->builtin_types.entry_i32->type_ref, 1, false);
2886 g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress", fn_type);
2887 assert(LLVMGetIntrinsicID(g->frame_address_fn_val));
2888
2889 return g->frame_address_fn_val;
2812}2890}
28132891
2814static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable,2892static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable,
2815 IrInstructionFrameAddress *instruction)2893 IrInstructionFrameAddress *instruction)
2816{2894{
2817 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref);2895 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref);
2818 return LLVMBuildCall(g->builder, g->frame_address_fn_val, &zero, 1, "");2896 return LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, "");
2819}2897}
28202898
2821static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {2899static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {
...@@ -3760,23 +3838,6 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const...@@ -3760,23 +3838,6 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const
3760 LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value);3838 LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value);
3761}3839}
37623840
3763static void delete_unused_builtin_fns(CodeGen *g) {
3764 // TODO get rid of this function
3765 auto it = g->builtin_fn_table.entry_iterator();
3766 for (;;) {
3767 auto *entry = it.next();
3768 if (!entry)
3769 break;
3770
3771 BuiltinFnEntry *builtin_fn = entry->value;
3772 if (builtin_fn->ref_count == 0 &&
3773 builtin_fn->fn_val)
3774 {
3775 LLVMDeleteFunction(entry->value->fn_val);
3776 }
3777 }
3778}
3779
3780static void generate_error_name_table(CodeGen *g) {3841static void generate_error_name_table(CodeGen *g) {
3781 if (g->err_name_table != nullptr || !g->generate_error_name_table || g->error_decls.length == 1) {3842 if (g->err_name_table != nullptr || !g->generate_error_name_table || g->error_decls.length == 1) {
3782 return;3843 return;
...@@ -3936,7 +3997,6 @@ static void do_code_gen(CodeGen *g) {...@@ -3936,7 +3997,6 @@ static void do_code_gen(CodeGen *g) {
39363997
3937 codegen_add_time_event(g, "Code Generation");3998 codegen_add_time_event(g, "Code Generation");
39383999
3939 delete_unused_builtin_fns(g);
3940 generate_error_name_table(g);4000 generate_error_name_table(g);
3941 generate_enum_name_tables(g);4001 generate_enum_name_tables(g);
39424002
...@@ -4528,81 +4588,11 @@ static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char...@@ -4528,81 +4588,11 @@ static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char
4528}4588}
45294589
4530static void define_builtin_fns(CodeGen *g) {4590static void define_builtin_fns(CodeGen *g) {
4531 {4591 create_builtin_fn(g, BuiltinFnIdBreakpoint, "breakpoint", 0);
4532 // TODO make lazy and get rid of delete_unused_builtin_fns4592 create_builtin_fn(g, BuiltinFnIdReturnAddress, "returnAddress", 0);
4533 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdBreakpoint, "breakpoint", 0);4593 create_builtin_fn(g, BuiltinFnIdFrameAddress, "frameAddress", 0);
4534 builtin_fn->ref_count = 1;4594 create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3);
45354595 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
4536 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false);
4537 builtin_fn->fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type);
4538 assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
4539
4540 g->trap_fn_val = builtin_fn->fn_val;
4541 }
4542 {
4543 // TODO make lazy and get rid of delete_unused_builtin_fns
4544 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdReturnAddress,
4545 "returnAddress", 0);
4546 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
4547
4548 LLVMTypeRef fn_type = LLVMFunctionType(return_type->type_ref,
4549 &g->builtin_types.entry_i32->type_ref, 1, false);
4550 builtin_fn->fn_val = LLVMAddFunction(g->module, "llvm.returnaddress", fn_type);
4551 assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
4552
4553 g->return_address_fn_val = builtin_fn->fn_val;
4554 }
4555 {
4556 // TODO make lazy and get rid of delete_unused_builtin_fns
4557 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdFrameAddress,
4558 "frameAddress", 0);
4559 TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
4560
4561 LLVMTypeRef fn_type = LLVMFunctionType(return_type->type_ref,
4562 &g->builtin_types.entry_i32->type_ref, 1, false);
4563 builtin_fn->fn_val = LLVMAddFunction(g->module, "llvm.frameaddress", fn_type);
4564 assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
4565
4566 g->frame_address_fn_val = builtin_fn->fn_val;
4567 }
4568 {
4569 // TODO make lazy and get rid of delete_unused_builtin_fns
4570 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3);
4571 builtin_fn->ref_count = 1;
4572
4573 LLVMTypeRef param_types[] = {
4574 LLVMPointerType(LLVMInt8Type(), 0),
4575 LLVMPointerType(LLVMInt8Type(), 0),
4576 LLVMIntType(g->pointer_size_bytes * 8),
4577 LLVMInt32Type(),
4578 LLVMInt1Type(),
4579 };
4580 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 5, false);
4581 Buf *name = buf_sprintf("llvm.memcpy.p0i8.p0i8.i%d", g->pointer_size_bytes * 8);
4582 builtin_fn->fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
4583 assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
4584
4585 g->memcpy_fn_val = builtin_fn->fn_val;
4586 }
4587 {
4588 // TODO make lazy and get rid of delete_unused_builtin_fns
4589 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
4590 builtin_fn->ref_count = 1;
4591
4592 LLVMTypeRef param_types[] = {
4593 LLVMPointerType(LLVMInt8Type(), 0),
4594 LLVMInt8Type(),
4595 LLVMIntType(g->pointer_size_bytes * 8),
4596 LLVMInt32Type(),
4597 LLVMInt1Type(),
4598 };
4599 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 5, false);
4600 Buf *name = buf_sprintf("llvm.memset.p0i8.i%d", g->pointer_size_bytes * 8);
4601 builtin_fn->fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
4602 assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
4603
4604 g->memset_fn_val = builtin_fn->fn_val;
4605 }
4606 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);4596 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);
4607 create_builtin_fn(g, BuiltinFnIdAlignof, "alignOf", 1);4597 create_builtin_fn(g, BuiltinFnIdAlignof, "alignOf", 1);
4608 create_builtin_fn(g, BuiltinFnIdMaxValue, "maxValue", 1);4598 create_builtin_fn(g, BuiltinFnIdMaxValue, "maxValue", 1);
src/ir.cpp-2
...@@ -3889,8 +3889,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -3889,8 +3889,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
3889 return irb->codegen->invalid_instruction;3889 return irb->codegen->invalid_instruction;
3890 }3890 }
38913891
3892 builtin_fn->ref_count += 1;
3893
3894 switch (builtin_fn->id) {3892 switch (builtin_fn->id) {
3895 case BuiltinFnIdInvalid:3893 case BuiltinFnIdInvalid:
3896 zig_unreachable();3894 zig_unreachable();