diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-02-25 17:57:05 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-02-25 17:57:05 -0500 |
| commit | fe354ebb5c71aa6c5600251d2c3db53b8c5dc8eb (patch) | |
| tree | a2b0583dbd56355d6f7df76792c69c5a060ee73d /src/ir.cpp | |
| parent | 704a8acb5997c7fdab4e29737fb398c022f876b7 (diff) | |
| download | zig-fe354ebb5c71aa6c5600251d2c3db53b8c5dc8eb.tar.gz zig-fe354ebb5c71aa6c5600251d2c3db53b8c5dc8eb.zip | |
coroutines: fix llvm error of instruction not dominating uses
See #727
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 81bde2e793..b3f53f824d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5983,6 +5983,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec IrInstruction *coro_id; IrInstruction *coro_promise_ptr; IrInstruction *coro_result_field_ptr; + IrInstruction *coro_need_dyn_alloc; TypeTableEntry *return_type; Buf *result_ptr_field_name; if (is_async) { @@ -6012,13 +6013,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr); coro_id = ir_build_coro_id(irb, scope, node, promise_as_u8_ptr); - IrInstruction *need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id); + coro_need_dyn_alloc = ir_build_coro_alloc(irb, scope, node, coro_id); IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero); IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc"); IrBasicBlock *coro_begin_block = ir_create_basic_block(irb, scope, "CoroBegin"); - ir_build_cond_br(irb, scope, node, need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false); + ir_build_cond_br(irb, scope, node, coro_need_dyn_alloc, dyn_alloc_block, coro_begin_block, const_bool_false); ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block); 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 ir_build_coro_alloc_fail(irb, scope, node, err_val); ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); - coro_unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); + IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false); Buf *ptr_field_name = buf_create_from_str("ptr"); - IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, coro_unwrapped_mem_ptr, + IrInstruction *coro_mem_ptr_field = ir_build_field_ptr(irb, scope, node, unwrapped_mem_ptr, ptr_field_name); IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field); ir_build_br(irb, scope, node, coro_begin_block, const_bool_false); ir_set_cursor_at_end_and_append_block(irb, coro_begin_block); - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); - incoming_blocks[0] = entry_block; - incoming_values[0] = null_ptr; - incoming_blocks[1] = alloc_ok_block; - incoming_values[1] = coro_mem_ptr; - IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); + + IrBasicBlock **coro_mem_incoming_blocks = allocate<IrBasicBlock *>(2); + IrInstruction **coro_mem_incoming_values = allocate<IrInstruction *>(2); + coro_mem_incoming_blocks[0] = entry_block; + coro_mem_incoming_values[0] = null_ptr; + coro_mem_incoming_blocks[1] = alloc_ok_block; + coro_mem_incoming_values[1] = coro_mem_ptr; + IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, coro_mem_incoming_blocks, coro_mem_incoming_values); + + IrBasicBlock **unwrapped_mem_ptr_incoming_blocks = allocate<IrBasicBlock *>(2); + IrInstruction **unwrapped_mem_ptr_incoming_values = allocate<IrInstruction *>(2); + unwrapped_mem_ptr_incoming_blocks[0] = entry_block; + unwrapped_mem_ptr_incoming_values[0] = ir_build_const_undefined(irb, scope, node); + unwrapped_mem_ptr_incoming_blocks[1] = alloc_ok_block; + unwrapped_mem_ptr_incoming_values[1] = unwrapped_mem_ptr; + coro_unwrapped_mem_ptr = ir_build_phi(irb, scope, node, 2, + unwrapped_mem_ptr_incoming_blocks, unwrapped_mem_ptr_incoming_values); + irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem); + irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); } @@ -6123,11 +6136,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec incoming_blocks[1] = irb->exec->coro_normal_final; incoming_values[1] = const_bool_true; IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); - IrInstruction *mem_to_free = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); - IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, mem_to_free); IrBasicBlock *dyn_free_block = ir_create_basic_block(irb, scope, "DynFree"); IrBasicBlock *end_free_block = ir_create_basic_block(irb, scope, "EndFree"); - ir_build_cond_br(irb, scope, node, is_non_null, dyn_free_block, end_free_block, const_bool_false); + ir_build_cond_br(irb, scope, node, coro_need_dyn_alloc, dyn_free_block, end_free_block, const_bool_false); ir_set_cursor_at_end_and_append_block(irb, dyn_free_block); Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME); |
