Skip to content

Commit fe354eb

Browse files
committed
coroutines: fix llvm error of instruction not dominating uses
See #727
1 parent 704a8ac commit fe354eb

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

src/ir.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5983,6 +5983,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
59835983
IrInstruction *coro_id;
59845984
IrInstruction *coro_promise_ptr;
59855985
IrInstruction *coro_result_field_ptr;
5986+
IrInstruction *coro_need_dyn_alloc;
59865987
TypeTableEntry *return_type;
59875988
Buf *result_ptr_field_name;
59885989
if (is_async) {
@@ -6012,13 +6013,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
60126013
get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false));
60136014
IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_promise_ptr);
60146015
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);
60166017
IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
60176018
IrInstruction *null_ptr = ir_build_int_to_ptr(irb, scope, node, u8_ptr_type, zero);
60186019

60196020
IrBasicBlock *dyn_alloc_block = ir_create_basic_block(irb, scope, "DynAlloc");
60206021
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

60236024
ir_set_cursor_at_end_and_append_block(irb, dyn_alloc_block);
60246025
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
60476048
ir_build_coro_alloc_fail(irb, scope, node, err_val);
60486049

60496050
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);
60516052
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,
60536054
ptr_field_name);
60546055
IrInstruction *coro_mem_ptr = ir_build_load_ptr(irb, scope, node, coro_mem_ptr_field);
60556056
ir_build_br(irb, scope, node, coro_begin_block, const_bool_false);
60566057

60576058
ir_set_cursor_at_end_and_append_block(irb, coro_begin_block);
6058-
IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
6059-
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
6060-
incoming_blocks[0] = entry_block;
6061-
incoming_values[0] = null_ptr;
6062-
incoming_blocks[1] = alloc_ok_block;
6063-
incoming_values[1] = coro_mem_ptr;
6064-
IrInstruction *coro_mem = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
6059+
6060+
IrBasicBlock **coro_mem_incoming_blocks = allocate<IrBasicBlock *>(2);
6061+
IrInstruction **coro_mem_incoming_values = allocate<IrInstruction *>(2);
6062+
coro_mem_incoming_blocks[0] = entry_block;
6063+
coro_mem_incoming_values[0] = null_ptr;
6064+
coro_mem_incoming_blocks[1] = alloc_ok_block;
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+
60656077
irb->exec->coro_handle = ir_build_coro_begin(irb, scope, node, coro_id, coro_mem);
6078+
60666079
irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
60676080
irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal");
60686081
}
@@ -6123,11 +6136,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
61236136
incoming_blocks[1] = irb->exec->coro_normal_final;
61246137
incoming_values[1] = const_bool_true;
61256138
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);
61286139
IrBasicBlock *dyn_free_block = ir_create_basic_block(irb, scope, "DynFree");
61296140
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

61326143
ir_set_cursor_at_end_and_append_block(irb, dyn_free_block);
61336144
Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);

0 commit comments

Comments
 (0)