authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-25 17:57:05-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-25 17:57:05-05:00
logfe354ebb5c71aa6c5600251d2c3db53b8c5dc8eb
treea2b0583dbd56355d6f7df76792c69c5a060ee73d
parent704a8acb5997c7fdab4e29737fb398c022f876b7

coroutines: fix llvm error of instruction not dominating uses

See #727

1 files changed, 25 insertions(+), 14 deletions(-)

src/ir.cpp+25-14
...@@ -5983,6 +5983,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -5983,6 +5983,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
5983 IrInstruction *coro_id;5983 IrInstruction *coro_id;
5984 IrInstruction *coro_promise_ptr;5984 IrInstruction *coro_promise_ptr;
5985 IrInstruction *coro_result_field_ptr;5985 IrInstruction *coro_result_field_ptr;
5986 IrInstruction *coro_need_dyn_alloc;
5986 TypeTableEntry *return_type;5987 TypeTableEntry *return_type;
5987 Buf *result_ptr_field_name;5988 Buf *result_ptr_field_name;
5988 if (is_async) {5989 if (is_async) {
...@@ -6012,13 +6013,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6012,13 +6013,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6012 get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false));6013 get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false));
6013 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr);6014 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr);
6014 coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr);6015 coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr);
6015 IrInstruction *need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id);6016 coro_need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id);
6016 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);6017 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
6017 IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero);6018 IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero);
60186019
6019 IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc");6020 IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc");
6020 IrBasicBlock *coro_begin_block = ir_create_basic_block(irb, scope, "CoroBegin");6021 IrBasicBlock *coro_begin_block = ir_create_basic_block(irb, scope, "CoroBegin");
6021 ir_build_cond_br(irb, scope, node, need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false);6022 ir_build_cond_br(irb, scope, node, coro_need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false);
60226023
6023 ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block);6024 ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block);
6024 IrInstruction *coro_size = ir_build_coro_size(irb, scope, node);6025 IrInstruction *coro_size = ir_build_coro_size(irb, scope, node);
...@@ -6047,22 +6048,34 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6047,22 +6048,34 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6047 ir_build_coro_alloc_fail(irb, scope, node, err_val);6048 ir_build_coro_alloc_fail(irb, scope, node, err_val);
60486049
6049 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);6050 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);
6050 coro_unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false);6051 IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false);
6051 Buf *ptr_field_name = buf_create_from_str("ptr");6052 Buf *ptr_field_name = buf_create_from_str("ptr");
6052 IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, coro_unwrapped_mem_ptr,6053 IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, unwrapped_mem_ptr,
6053 ptr_field_name);6054 ptr_field_name);
6054 IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field);6055 IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field);
6055 ir_build_br(irb, scope, node, coro_begin_block, const_bool_false);6056 ir_build_br(irb, scope, node, coro_begin_block, const_bool_false);
60566057
6057 ir_set_cursor_at_end_and_append_block(irb, coro_begin_block);6058 ir_set_cursor_at_end_and_append_block(irb, coro_begin_block);
6058 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);6059
6059 IrInstruction **incoming_values = allocate<IrInstruction *>(2);6060 IrBasicBlock **coro_mem_incoming_blocks = allocate<IrBasicBlock *>(2);
6060 incoming_blocks[0] = entry_block;6061 IrInstruction **coro_mem_incoming_values = allocate<IrInstruction *>(2);
6061 incoming_values[0] = null_ptr;6062 coro_mem_incoming_blocks[0] = entry_block;
6062 incoming_blocks[1] = alloc_ok_block;6063 coro_mem_incoming_values[0] = null_ptr;
6063 incoming_values[1] = coro_mem_ptr;6064 coro_mem_incoming_blocks[1] = alloc_ok_block;
6064 IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);6065 coro_mem_incoming_values[1] = coro_mem_ptr;
6066 IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, coro_mem_incoming_blocks, coro_mem_incoming_values);
6067
6068 IrBasicBlock **unwrapped_mem_ptr_incoming_blocks = allocate<IrBasicBlock *>(2);
6069 IrInstruction **unwrapped_mem_ptr_incoming_values = allocate<IrInstruction *>(2);
6070 unwrapped_mem_ptr_incoming_blocks[0] = entry_block;
6071 unwrapped_mem_ptr_incoming_values[0] = ir_build_const_undefined(irb, scope, node);
6072 unwrapped_mem_ptr_incoming_blocks[1] = alloc_ok_block;
6073 unwrapped_mem_ptr_incoming_values[1] = unwrapped_mem_ptr;
6074 coro_unwrapped_mem_ptr = ir_build_phi(irb, scope, node, 2,
6075 unwrapped_mem_ptr_incoming_blocks, unwrapped_mem_ptr_incoming_values);
6076
6065 irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem);6077 irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem);
6078
6066 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");6079 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
6067 irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal");6080 irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal");
6068 }6081 }
...@@ -6123,11 +6136,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6123,11 +6136,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6123 incoming_blocks[1] = irb->exec->coro_normal_final;6136 incoming_blocks[1] = irb->exec->coro_normal_final;
6124 incoming_values[1] = const_bool_true;6137 incoming_values[1] = const_bool_true;
6125 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);6138 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
6126 IrInstruction *mem_to_free = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
6127 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, mem_to_free);
6128 IrBasicBlock *dyn_free_block = ir_create_basic_block(irb, scope, "DynFree");6139 IrBasicBlock *dyn_free_block = ir_create_basic_block(irb, scope, "DynFree");
6129 IrBasicBlock *end_free_block = ir_create_basic_block(irb, scope, "EndFree");6140 IrBasicBlock *end_free_block = ir_create_basic_block(irb, scope, "EndFree");
6130 ir_build_cond_br(irb, scope, node, is_non_null, dyn_free_block, end_free_block, const_bool_false);6141 ir_build_cond_br(irb, scope, node, coro_need_dyn_alloc, dyn_free_block, end_free_block, const_bool_false);
61316142
6132 ir_set_cursor_at_end_and_append_block(irb, dyn_free_block);6143 ir_set_cursor_at_end_and_append_block(irb, dyn_free_block);
6133 Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);6144 Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);