authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-27 14:58:02-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-27 14:58:02-05:00
log6e2a67724c576420c1c0f005ccebdc6b0e708724
treeb0ce3a75a10248bcbc0350afd83928f7a88baea1
parentc2f5634fb3df51622cf74f23b4ae0d4a7d2bbbe9

Revert "another llvm workaround for getelementptr"

This reverts commit c2f5634fb3df51622cf74f23b4ae0d4a7d2bbbe9. It doesn't work. With this, LLVM moves the allocate fn call to after llvm.coro.begin

3 files changed, 6 insertions(+), 81 deletions(-)

src/all_types.hpp+1-10
...@@ -1461,14 +1461,6 @@ struct LinkLib {...@@ -1461,14 +1461,6 @@ struct LinkLib {
1461 bool provided_explicitly;1461 bool provided_explicitly;
1462};1462};
14631463
1464struct WorkaroundStructGEPId {
1465 LLVMTypeRef struct_ptr_type;
1466 uint32_t index;
1467};
1468
1469uint32_t workaround_struct_gep_hash(WorkaroundStructGEPId x);
1470bool workaround_struct_gep_eq(WorkaroundStructGEPId a, WorkaroundStructGEPId b);
1471
1472struct CodeGen {1464struct CodeGen {
1473 LLVMModuleRef module;1465 LLVMModuleRef module;
1474 ZigList<ErrorMsg*> errors;1466 ZigList<ErrorMsg*> errors;
...@@ -1499,7 +1491,7 @@ struct CodeGen {...@@ -1499,7 +1491,7 @@ struct CodeGen {
1499 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;1491 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
1500 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;1492 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
1501 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;1493 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;
1502 HashMap<WorkaroundStructGEPId, LLVMValueRef, workaround_struct_gep_hash, workaround_struct_gep_eq> workaround_struct_gep_table;1494
15031495
1504 ZigList<ImportTableEntry *> import_queue;1496 ZigList<ImportTableEntry *> import_queue;
1505 size_t import_queue_index;1497 size_t import_queue_index;
...@@ -1611,7 +1603,6 @@ struct CodeGen {...@@ -1611,7 +1603,6 @@ struct CodeGen {
1611 LLVMValueRef cur_ret_ptr;1603 LLVMValueRef cur_ret_ptr;
1612 LLVMValueRef cur_fn_val;1604 LLVMValueRef cur_fn_val;
1613 LLVMValueRef cur_err_ret_trace_val;1605 LLVMValueRef cur_err_ret_trace_val;
1614 bool cur_workaround_gep_on;
1615 bool c_want_stdint;1606 bool c_want_stdint;
1616 bool c_want_stdbool;1607 bool c_want_stdbool;
1617 AstNode *root_export_decl;1608 AstNode *root_export_decl;
src/analyze.cpp-8
...@@ -5821,11 +5821,3 @@ bool type_is_global_error_set(TypeTableEntry *err_set_type) {...@@ -5821,11 +5821,3 @@ bool type_is_global_error_set(TypeTableEntry *err_set_type) {
5821uint32_t get_coro_frame_align_bytes(CodeGen *g) {5821uint32_t get_coro_frame_align_bytes(CodeGen *g) {
5822 return g->pointer_size_bytes * 2;5822 return g->pointer_size_bytes * 2;
5823}5823}
5824
5825uint32_t workaround_struct_gep_hash(WorkaroundStructGEPId x) {
5826 return ptr_hash(x.struct_ptr_type) ^ x.index;
5827}
5828
5829bool workaround_struct_gep_eq(WorkaroundStructGEPId a, WorkaroundStructGEPId b) {
5830 return a.struct_ptr_type == b.struct_ptr_type && a.index == b.index;
5831}
src/codegen.cpp+5-63
...@@ -88,7 +88,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out...@@ -88,7 +88,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
88 g->exported_symbol_names.init(8);88 g->exported_symbol_names.init(8);
89 g->external_prototypes.init(8);89 g->external_prototypes.init(8);
90 g->string_literals_table.init(16);90 g->string_literals_table.init(16);
91 g->workaround_struct_gep_table.init(8);
92 g->is_test_build = false;91 g->is_test_build = false;
93 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);92 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
94 buf_resize(&g->global_asm, 0);93 buf_resize(&g->global_asm, 0);
...@@ -2782,52 +2781,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -2782,52 +2781,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
2782 }2781 }
2783}2782}
27842783
2785static LLVMValueRef get_workaround_struct_gep_fn_val(CodeGen *g, LLVMTypeRef struct_ptr_type, uint32_t index) {
2786 WorkaroundStructGEPId hash_id = {struct_ptr_type, index};
2787 auto existing_entry = g->workaround_struct_gep_table.maybe_get(hash_id);
2788 if (existing_entry)
2789 return existing_entry->value;
2790
2791 LLVMTypeRef arg_types[] = {
2792 struct_ptr_type,
2793 };
2794 LLVMTypeRef result_type = LLVMStructGetTypeAtIndex(LLVMGetElementType(struct_ptr_type), index);
2795 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(result_type, 0), arg_types, 1, false);
2796
2797 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_workaround_llvm_struct_gep"), false);
2798 LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
2799 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
2800 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
2801 addLLVMFnAttr(fn_val, "nounwind");
2802 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
2803
2804 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
2805 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
2806 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder);
2807 LLVMPositionBuilderAtEnd(g->builder, entry_block);
2808 ZigLLVMClearCurrentDebugLocation(g->builder);
2809
2810 LLVMValueRef result = LLVMBuildStructGEP(g->builder, LLVMGetParam(fn_val, 0), index, "");
2811 LLVMBuildRet(g->builder, result);
2812
2813 LLVMPositionBuilderAtEnd(g->builder, prev_block);
2814 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
2815
2816 g->workaround_struct_gep_table.put(hash_id, fn_val);
2817 return fn_val;
2818}
2819
2820static LLVMValueRef gen_workaround_struct_gep(CodeGen *g, LLVMValueRef struct_ptr, uint32_t field_index) {
2821 if (g->cur_workaround_gep_on) {
2822 // We need to generate a normal StructGEP but due to llvm bugs we have to workaround it by
2823 // putting the GEP in a function call
2824 LLVMValueRef fn_val = get_workaround_struct_gep_fn_val(g, LLVMTypeOf(struct_ptr), field_index);
2825 return LLVMBuildCall(g->builder, fn_val, &struct_ptr, 1, "");
2826 } else {
2827 return LLVMBuildStructGEP(g->builder, struct_ptr, field_index, "");
2828 }
2829}
2830
2831static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,2784static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
2832 IrInstructionStructFieldPtr *instruction)2785 IrInstructionStructFieldPtr *instruction)
2833{2786{
...@@ -2846,7 +2799,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa...@@ -2846,7 +2799,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
2846 }2799 }
28472800
2848 assert(field->gen_index != SIZE_MAX);2801 assert(field->gen_index != SIZE_MAX);
2849 return gen_workaround_struct_gep(g, struct_ptr, field->gen_index);2802 return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
2850}2803}
28512804
2852static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,2805static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,
...@@ -3702,7 +3655,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI...@@ -3702,7 +3655,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
37023655
3703 LLVMValueRef err_val;3656 LLVMValueRef err_val;
3704 if (type_has_bits(payload_type)) {3657 if (type_has_bits(payload_type)) {
3705 LLVMValueRef err_val_ptr = gen_workaround_struct_gep(g, err_union_handle, err_union_err_index);3658 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3706 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");3659 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
3707 } else {3660 } else {
3708 err_val = err_union_handle;3661 err_val = err_union_handle;
...@@ -3721,12 +3674,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab...@@ -3721,12 +3674,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
3721 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);3674 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
37223675
3723 if (type_has_bits(payload_type)) {3676 if (type_has_bits(payload_type)) {
3724 LLVMValueRef err_val_ptr;3677 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3725 if (g->cur_workaround_gep_on) {
3726 err_val_ptr = gen_workaround_struct_gep(g, err_union_handle, err_union_err_index);
3727 } else {
3728 err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3729 }
3730 return gen_load_untyped(g, err_val_ptr, 0, false, "");3678 return gen_load_untyped(g, err_val_ptr, 0, false, "");
3731 } else {3679 } else {
3732 return err_union_handle;3680 return err_union_handle;
...@@ -3748,7 +3696,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -3748,7 +3696,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
3748 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->errors_by_index.length > 1) {3696 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->errors_by_index.length > 1) {
3749 LLVMValueRef err_val;3697 LLVMValueRef err_val;
3750 if (type_has_bits(payload_type)) {3698 if (type_has_bits(payload_type)) {
3751 LLVMValueRef err_val_ptr = gen_workaround_struct_gep(g, err_union_handle, err_union_err_index);3699 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3752 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");3700 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
3753 } else {3701 } else {
3754 err_val = err_union_handle;3702 err_val = err_union_handle;
...@@ -3766,11 +3714,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -3766,11 +3714,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
3766 }3714 }
37673715
3768 if (type_has_bits(payload_type)) {3716 if (type_has_bits(payload_type)) {
3769 if (g->cur_workaround_gep_on) {3717 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
3770 return gen_workaround_struct_gep(g, err_union_handle, err_union_payload_index);
3771 } else {
3772 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
3773 }
3774 } else {3718 } else {
3775 return nullptr;3719 return nullptr;
3776 }3720 }
...@@ -3990,7 +3934,6 @@ static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, I...@@ -3990,7 +3934,6 @@ static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, I
3990 coro_id,3934 coro_id,
3991 coro_mem_ptr,3935 coro_mem_ptr,
3992 };3936 };
3993 g->cur_workaround_gep_on = false;
3994 return LLVMBuildCall(g->builder, get_coro_begin_fn_val(g), params, 2, "");3937 return LLVMBuildCall(g->builder, get_coro_begin_fn_val(g), params, 2, "");
3995}3938}
39963939
...@@ -5130,7 +5073,6 @@ static void do_code_gen(CodeGen *g) {...@@ -5130,7 +5073,6 @@ static void do_code_gen(CodeGen *g) {
5130 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry);5073 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry);
5131 g->cur_fn = fn_table_entry;5074 g->cur_fn = fn_table_entry;
5132 g->cur_fn_val = fn;5075 g->cur_fn_val = fn;
5133 g->cur_workaround_gep_on = fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
5134 TypeTableEntry *return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;5076 TypeTableEntry *return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
5135 if (handle_is_ptr(return_type)) {5077 if (handle_is_ptr(return_type)) {
5136 g->cur_ret_ptr = LLVMGetParam(fn, 0);5078 g->cur_ret_ptr = LLVMGetParam(fn, 0);