| ... | @@ -185,7 +185,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -185,7 +185,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc |
| 185 | ZigType *ptr_type); | 185 | ZigType *ptr_type); |
| 186 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 186 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 187 | ZigType *dest_type); | 187 | ZigType *dest_type); |
| 188 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); | 188 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 189 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); |
| 189 | | 190 | |
| 190 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 191 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 191 | assert(get_src_ptr_type(const_val->type) != nullptr); | 192 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -1376,11 +1377,8 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -1376,11 +1377,8 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s |
| 1376 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, | 1377 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1377 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, | 1378 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1378 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, | 1379 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| 1379 | ResultLoc *result_loc, ZigType *return_type) | 1380 | IrInstruction *result_loc, ZigType *return_type) |
| 1380 | { | 1381 | { |
| 1381 | // must be resolved before building the call instruction | | |
| 1382 | IrInstruction *resolved_result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr); | | |
| 1383 | | | |
| 1384 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, | 1382 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| 1385 | source_instruction->scope, source_instruction->source_node); | 1383 | source_instruction->scope, source_instruction->source_node); |
| 1386 | call_instruction->base.value.type = return_type; | 1384 | call_instruction->base.value.type = return_type; |
| ... | @@ -1392,14 +1390,14 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -1392,14 +1390,14 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in |
| 1392 | call_instruction->is_async = is_async; | 1390 | call_instruction->is_async = is_async; |
| 1393 | call_instruction->async_allocator = async_allocator; | 1391 | call_instruction->async_allocator = async_allocator; |
| 1394 | call_instruction->new_stack = new_stack; | 1392 | call_instruction->new_stack = new_stack; |
| 1395 | call_instruction->result_loc = resolved_result_loc; | 1393 | call_instruction->result_loc = result_loc; |
| 1396 | | 1394 | |
| 1397 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); | 1395 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| 1398 | for (size_t i = 0; i < arg_count; i += 1) | 1396 | for (size_t i = 0; i < arg_count; i += 1) |
| 1399 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); | 1397 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| 1400 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); | 1398 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| 1401 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); | 1399 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| 1402 | if (call_instruction->result_loc != nullptr) ir_ref_instruction(call_instruction->result_loc, ira->new_irb.current_basic_block); | 1400 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1403 | | 1401 | |
| 1404 | return &call_instruction->base; | 1402 | return &call_instruction->base; |
| 1405 | } | 1403 | } |
| ... | @@ -5366,7 +5364,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5366,7 +5364,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5366 | incoming_blocks[1] = after_else_block; | 5364 | incoming_blocks[1] = after_else_block; |
| 5367 | | 5365 | |
| 5368 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 5366 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 5369 | return ir_lval_wrap(irb, scope, phi, lval, result_loc); | 5367 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5370 | } | 5368 | } |
| 5371 | | 5369 | |
| 5372 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { | 5370 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { |
| ... | @@ -6558,10 +6556,11 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit | ... | @@ -6558,10 +6556,11 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6558 | return true; | 6556 | return true; |
| 6559 | } | 6557 | } |
| 6560 | | 6558 | |
| 6561 | static void next_peer_block(ZigList<ResultLocPeer> *list, IrBasicBlock *next_bb) { | 6559 | static void next_peer_block(ResultLocPeerParent *peer_parent, IrBasicBlock *next_bb) { |
| 6562 | if (list->length >= 2) { | 6560 | if (peer_parent->peer_count > 0) { |
| 6563 | list->at(list->length - 2).next_bb = next_bb; | 6561 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = next_bb; |
| 6564 | } | 6562 | } |
| | 6563 | peer_parent->peer_count += 1; |
| 6565 | } | 6564 | } |
| 6566 | | 6565 | |
| 6567 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, | 6566 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| ... | @@ -6600,8 +6599,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6600,8 +6599,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6600 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); | 6599 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 6601 | peer_parent->base.id = ResultLocIdPeerParent; | 6600 | peer_parent->base.id = ResultLocIdPeerParent; |
| 6602 | peer_parent->parent = result_loc; | 6601 | peer_parent->parent = result_loc; |
| 6603 | | 6602 | peer_parent->peers = allocate<ResultLocPeer>(prong_count); |
| 6604 | ZigList<ResultLocPeer> peer_result_locs = {}; | 6603 | peer_parent->peer_count = 0; |
| 6605 | | 6604 | |
| 6606 | // First do the else and the ranges | 6605 | // First do the else and the ranges |
| 6607 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 6606 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| ... | @@ -6611,7 +6610,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6611,7 +6610,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6611 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); | 6610 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6612 | size_t prong_item_count = prong_node->data.switch_prong.items.length; | 6611 | size_t prong_item_count = prong_node->data.switch_prong.items.length; |
| 6613 | if (prong_item_count == 0) { | 6612 | if (prong_item_count == 0) { |
| 6614 | ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one(); | 6613 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; |
| 6615 | this_peer_result_loc->base.id = ResultLocIdPeer; | 6614 | this_peer_result_loc->base.id = ResultLocIdPeer; |
| 6616 | this_peer_result_loc->parent = peer_parent; | 6615 | this_peer_result_loc->parent = peer_parent; |
| 6617 | if (else_prong) { | 6616 | if (else_prong) { |
| ... | @@ -6624,7 +6623,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6624,7 +6623,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6624 | else_prong = prong_node; | 6623 | else_prong = prong_node; |
| 6625 | | 6624 | |
| 6626 | IrBasicBlock *prev_block = irb->current_basic_block; | 6625 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6627 | next_peer_block(&peer_result_locs, else_block); | 6626 | next_peer_block(peer_parent, else_block); |
| 6628 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6627 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6629 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 6628 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6630 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, | 6629 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, |
| ... | @@ -6634,7 +6633,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6634,7 +6633,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6634 | } | 6633 | } |
| 6635 | ir_set_cursor_at_end(irb, prev_block); | 6634 | ir_set_cursor_at_end(irb, prev_block); |
| 6636 | } else if (prong_node->data.switch_prong.any_items_are_range) { | 6635 | } else if (prong_node->data.switch_prong.any_items_are_range) { |
| 6637 | ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one(); | 6636 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; |
| 6638 | this_peer_result_loc->base.id = ResultLocIdPeer; | 6637 | this_peer_result_loc->base.id = ResultLocIdPeer; |
| 6639 | this_peer_result_loc->parent = peer_parent; | 6638 | this_peer_result_loc->parent = peer_parent; |
| 6640 | | 6639 | |
| ... | @@ -6697,7 +6696,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6697,7 +6696,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6697 | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, | 6696 | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, |
| 6698 | range_block_no, is_comptime)); | 6697 | range_block_no, is_comptime)); |
| 6699 | | 6698 | |
| 6700 | next_peer_block(&peer_result_locs, range_block_yes); | 6699 | next_peer_block(peer_parent, range_block_yes); |
| 6701 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); | 6700 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 6702 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 6701 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6703 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, | 6702 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| ... | @@ -6719,7 +6718,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6719,7 +6718,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6719 | if (prong_node->data.switch_prong.any_items_are_range) | 6718 | if (prong_node->data.switch_prong.any_items_are_range) |
| 6720 | continue; | 6719 | continue; |
| 6721 | | 6720 | |
| 6722 | ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one(); | 6721 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; |
| 6723 | this_peer_result_loc->base.id = ResultLocIdPeer; | 6722 | this_peer_result_loc->base.id = ResultLocIdPeer; |
| 6724 | this_peer_result_loc->parent = peer_parent; | 6723 | this_peer_result_loc->parent = peer_parent; |
| 6725 | | 6724 | |
| ... | @@ -6746,7 +6745,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6746,7 +6745,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6746 | } | 6745 | } |
| 6747 | | 6746 | |
| 6748 | IrBasicBlock *prev_block = irb->current_basic_block; | 6747 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6749 | next_peer_block(&peer_result_locs, prong_block); | 6748 | next_peer_block(peer_parent, prong_block); |
| 6750 | ir_set_cursor_at_end_and_append_block(irb, prong_block); | 6749 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6751 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 6750 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6752 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, | 6751 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, |
| ... | @@ -6773,22 +6772,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6773,22 +6772,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6773 | } | 6772 | } |
| 6774 | br_instruction = &switch_br->base; | 6773 | br_instruction = &switch_br->base; |
| 6775 | } | 6774 | } |
| 6776 | for (size_t i = 0; i < peer_result_locs.length; i += 1) { | 6775 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 6777 | peer_result_locs.at(i).base.source_instruction = br_instruction; | 6776 | peer_parent->peers[i].base.source_instruction = br_instruction; |
| 6778 | } | 6777 | } |
| 6779 | peer_parent->base.source_instruction = br_instruction; | 6778 | peer_parent->base.source_instruction = br_instruction; |
| 6780 | peer_parent->peer_count = peer_result_locs.length; | | |
| 6781 | peer_parent->peers = peer_result_locs.items; | | |
| 6782 | | 6779 | |
| 6783 | if (!else_prong) { | 6780 | if (!else_prong) { |
| 6784 | if (peer_result_locs.length != 0) { | 6781 | if (peer_parent->peer_count != 0) { |
| 6785 | peer_result_locs.last().next_bb = else_block; | 6782 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = else_block; |
| 6786 | } | 6783 | } |
| 6787 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6784 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6788 | ir_build_unreachable(irb, scope, node); | 6785 | ir_build_unreachable(irb, scope, node); |
| 6789 | } else { | 6786 | } else { |
| 6790 | if (peer_result_locs.length != 0) { | 6787 | if (peer_parent->peer_count != 0) { |
| 6791 | peer_result_locs.last().next_bb = end_block; | 6788 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = end_block; |
| 6792 | } | 6789 | } |
| 6793 | } | 6790 | } |
| 6794 | | 6791 | |
| ... | @@ -14400,12 +14397,12 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo | ... | @@ -14400,12 +14397,12 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo |
| 14400 | | 14397 | |
| 14401 | // give nullptr for value to resolve it at runtime | 14398 | // give nullptr for value to resolve it at runtime |
| 14402 | // returns a result location, or nullptr if the result location was already taken care of | 14399 | // returns a result location, or nullptr if the result location was already taken care of |
| 14403 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type, | 14400 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 14404 | IrInstruction *value) | 14401 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 14402 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value) |
| 14405 | { | 14403 | { |
| 14406 | if (result_loc->implicit_elem_type != nullptr) { | 14404 | if (result_loc->resolved_loc != nullptr) { |
| 14407 | // already resolved | 14405 | return result_loc->resolved_loc; |
| 14408 | return nullptr; | | |
| 14409 | } | 14406 | } |
| 14410 | result_loc->gen_instruction = value; | 14407 | result_loc->gen_instruction = value; |
| 14411 | result_loc->implicit_elem_type = value_type; | 14408 | result_loc->implicit_elem_type = value_type; |
| ... | @@ -14420,12 +14417,12 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z | ... | @@ -14420,12 +14417,12 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z |
| 14420 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); | 14417 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); |
| 14421 | IrInstructionAllocaSrc *alloca_src = | 14418 | IrInstructionAllocaSrc *alloca_src = |
| 14422 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); | 14419 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| | 14420 | bool force_comptime; |
| | 14421 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| | 14422 | return ira->codegen->invalid_instruction; |
| | 14423 | bool is_comptime = force_comptime || (value != nullptr && |
| | 14424 | value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| 14423 | if (alloca_src->base.child == nullptr) { | 14425 | if (alloca_src->base.child == nullptr) { |
| 14424 | bool force_comptime; | | |
| 14425 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) | | |
| 14426 | return ira->codegen->invalid_instruction; | | |
| 14427 | bool is_comptime = force_comptime || (value != nullptr && | | |
| 14428 | value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); | | |
| 14429 | uint32_t align = 0; | 14426 | uint32_t align = 0; |
| 14430 | if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) { | 14427 | if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) { |
| 14431 | return ira->codegen->invalid_instruction; | 14428 | return ira->codegen->invalid_instruction; |
| ... | @@ -14441,18 +14438,67 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z | ... | @@ -14441,18 +14438,67 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z |
| 14441 | alloca_src->name_hint, force_comptime); | 14438 | alloca_src->name_hint, force_comptime); |
| 14442 | } | 14439 | } |
| 14443 | alloca_src->base.child = alloca_gen; | 14440 | alloca_src->base.child = alloca_gen; |
| 14444 | return is_comptime ? nullptr : alloca_src->base.child; | | |
| 14445 | } | 14441 | } |
| 14446 | return nullptr; | 14442 | result_loc->written = true; |
| | 14443 | result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; |
| | 14444 | return result_loc->resolved_loc; |
| 14447 | } | 14445 | } |
| 14448 | case ResultLocIdReturn: { | 14446 | case ResultLocIdReturn: { |
| 14449 | bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime; | 14447 | bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime; |
| 14450 | if (is_comptime) return nullptr; | 14448 | if (is_comptime) return nullptr; |
| 14451 | ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); | 14449 | ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); |
| 14452 | return ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); | 14450 | result_loc->written = true; |
| | 14451 | result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); |
| | 14452 | return result_loc->resolved_loc; |
| | 14453 | } |
| | 14454 | case ResultLocIdPeer: { |
| | 14455 | ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); |
| | 14456 | ResultLocPeerParent *peer_parent = result_peer->parent; |
| | 14457 | |
| | 14458 | if (ira->const_predecessor_bb) |
| | 14459 | return nullptr; |
| | 14460 | |
| | 14461 | if (peer_parent->resolved_type == nullptr) { |
| | 14462 | IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr, |
| | 14463 | result_peer->next_bb, &result_peer->suspend_pos); |
| | 14464 | bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]); |
| | 14465 | if (!last_one) { |
| | 14466 | return suspended_inst; |
| | 14467 | } |
| | 14468 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| | 14469 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| | 14470 | ResultLocPeer *this_peer = &peer_parent->peers[i]; |
| | 14471 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| | 14472 | |
| | 14473 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| | 14474 | if (gen_instruction == nullptr) { |
| | 14475 | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| | 14476 | this_peer->base.implicit_elem_type); |
| | 14477 | instructions[i]->value.special = ConstValSpecialRuntime; |
| | 14478 | } else { |
| | 14479 | instructions[i] = gen_instruction; |
| | 14480 | } |
| | 14481 | if (opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) { |
| | 14482 | ira->resume_stack.append(opposite_peer->suspend_pos); |
| | 14483 | } |
| | 14484 | } |
| | 14485 | ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent); |
| | 14486 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| | 14487 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| | 14488 | peer_parent->peer_count); |
| | 14489 | return ira_resume(ira); |
| | 14490 | } |
| | 14491 | |
| | 14492 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| | 14493 | peer_parent->resolved_type, nullptr); |
| | 14494 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| | 14495 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 14496 | { |
| | 14497 | return parent_result_loc; |
| | 14498 | } |
| | 14499 | result_loc->resolved_loc = parent_result_loc; |
| | 14500 | return result_loc->resolved_loc; |
| 14453 | } | 14501 | } |
| 14454 | case ResultLocIdPeer: | | |
| 14455 | return nullptr; | | |
| 14456 | } | 14502 | } |
| 14457 | zig_unreachable(); | 14503 | zig_unreachable(); |
| 14458 | } | 14504 | } |
| ... | @@ -14504,7 +14550,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc | ... | @@ -14504,7 +14550,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc |
| 14504 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); | 14550 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 14505 | | 14551 | |
| 14506 | return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, | 14552 | return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| 14507 | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, call_instruction->result_loc, | 14553 | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, nullptr, |
| 14508 | async_return_type); | 14554 | async_return_type); |
| 14509 | } | 14555 | } |
| 14510 | | 14556 | |
| ... | @@ -15246,6 +15292,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15246,6 +15292,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15246 | } | 15292 | } |
| 15247 | | 15293 | |
| 15248 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; | 15294 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; |
| | 15295 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| | 15296 | impl_fn_type_id->return_type, nullptr); |
| | 15297 | if (result_loc != nullptr && |
| | 15298 | (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable)) |
| | 15299 | { |
| | 15300 | return result_loc; |
| | 15301 | } |
| | 15302 | |
| 15249 | if (fn_type_can_fail(impl_fn_type_id)) { | 15303 | if (fn_type_can_fail(impl_fn_type_id)) { |
| 15250 | parent_fn_entry->calls_or_awaits_errorable_fn = true; | 15304 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 15251 | } | 15305 | } |
| ... | @@ -15257,10 +15311,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15257,10 +15311,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15257 | return ir_finish_anal(ira, result); | 15311 | return ir_finish_anal(ira, result); |
| 15258 | } | 15312 | } |
| 15259 | | 15313 | |
| | 15314 | call_instruction->result_loc->written = true; |
| 15260 | assert(async_allocator_inst == nullptr); | 15315 | assert(async_allocator_inst == nullptr); |
| 15261 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, | 15316 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 15262 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, | 15317 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 15263 | call_instruction->is_async, nullptr, casted_new_stack, call_instruction->result_loc, | 15318 | call_instruction->is_async, nullptr, casted_new_stack, result_loc, |
| 15264 | impl_fn_type_id->return_type); | 15319 | impl_fn_type_id->return_type); |
| 15265 | | 15320 | |
| 15266 | return ir_finish_anal(ira, new_call_instruction); | 15321 | return ir_finish_anal(ira, new_call_instruction); |
| ... | @@ -15355,9 +15410,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15355,9 +15410,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15355 | return ira->codegen->invalid_instruction; | 15410 | return ira->codegen->invalid_instruction; |
| 15356 | } | 15411 | } |
| 15357 | | 15412 | |
| | 15413 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| | 15414 | return_type, nullptr); |
| | 15415 | if (result_loc != nullptr && |
| | 15416 | (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable)) |
| | 15417 | { |
| | 15418 | return result_loc; |
| | 15419 | } |
| | 15420 | |
| | 15421 | call_instruction->result_loc->written = true; |
| 15358 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, | 15422 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 15359 | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, | 15423 | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, |
| 15360 | call_instruction->result_loc, return_type); | 15424 | result_loc, return_type); |
| 15361 | return ir_finish_anal(ira, new_call_instruction); | 15425 | return ir_finish_anal(ira, new_call_instruction); |
| 15362 | } | 15426 | } |
| 15363 | | 15427 | |
| ... | @@ -23619,35 +23683,19 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct | ... | @@ -23619,35 +23683,19 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 23619 | if (type_is_invalid(value->value.type)) | 23683 | if (type_is_invalid(value->value.type)) |
| 23620 | return ira->codegen->invalid_instruction; | 23684 | return ira->codegen->invalid_instruction; |
| 23621 | | 23685 | |
| 23622 | if (instruction->result_loc->id == ResultLocIdPeer) { | 23686 | if (!instruction->result_loc->written) { |
| 23623 | ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(instruction->result_loc); | 23687 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 23624 | ResultLocPeerParent *peer_parent = result_peer->parent; | 23688 | value->value.type, value); |
| | 23689 | if (result_loc != nullptr) { |
| | 23690 | if (type_is_invalid(result_loc->value.type)) |
| | 23691 | return ira->codegen->invalid_instruction; |
| | 23692 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 23693 | return result_loc; |
| 23625 | | 23694 | |
| 23626 | if (peer_parent->resolved_type == nullptr && !ira->const_predecessor_bb) { | 23695 | instruction->result_loc->written = true; |
| 23627 | instruction->result_loc->implicit_elem_type = value->value.type; | 23696 | ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| 23628 | instruction->result_loc->gen_instruction = value; | | |
| 23629 | IrInstruction *suspended_inst = ira_suspend(ira, &instruction->base, result_peer->next_bb, | | |
| 23630 | &result_peer->suspend_pos); | | |
| 23631 | bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]); | | |
| 23632 | if (!last_one) { | | |
| 23633 | return suspended_inst; | | |
| 23634 | } | | |
| 23635 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); | | |
| 23636 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { | | |
| 23637 | instructions[i] = peer_parent->peers[i].base.gen_instruction; | | |
| 23638 | ira->resume_stack.append(peer_parent->peers[peer_parent->peer_count - i - 1].suspend_pos); | | |
| 23639 | } | | |
| 23640 | ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent); | | |
| 23641 | peer_parent->resolved_type = ir_resolve_peer_types(ira, | | |
| 23642 | peer_parent->base.source_instruction->source_node, expected_type, instructions, | | |
| 23643 | peer_parent->peer_count); | | |
| 23644 | return ira_resume(ira); | | |
| 23645 | } | 23697 | } |
| 23646 | } | 23698 | } |
| 23647 | IrInstruction *result_loc = ir_resolve_result(ira, instruction->result_loc, value->value.type, value); | | |
| 23648 | if (result_loc != nullptr && !type_is_invalid(result_loc->value.type)) { | | |
| 23649 | ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); | | |
| 23650 | } | | |
| 23651 | | 23699 | |
| 23652 | return ir_const_void(ira, &instruction->base); | 23700 | return ir_const_void(ira, &instruction->base); |
| 23653 | } | 23701 | } |